--- /dev/null
+dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+dnl
+dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+dnl
+dnl
+dnl
+
+AC_DEFUN([CHECK_PLATFORM],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+
+AC_CHECKING(for Platform)
+
+AC_SUBST(PLATFORM_INCLUDES)
+
+PLATFORM_INCLUDES="PCLINUX"
+SUFFIXES=""
+
+f77int="F77INT32"
+case $host_os in
+ irix5.* | irix6.* | osf4.* | osf5.* | linux* )
+
+ linux64="true"
+ expr "$host_os" : 'linux' >/dev/null && test ! x"$host_cpu" = x"x86_64" && linux64="false"
+ if test ! x"$linux64" = "xfalse" ; then
+ echo "$as_me:$LINENO: checking for 64bits integers size in F77/F90" >&5
+echo $ECHO_N "checking for 64bits integers size in F77/F90... $ECHO_C" >&6
+ # Check whether --enable-int64 or --disable-int64 was given.
+if test "${enable_int64+set}" = set; then
+ enableval="$enable_int64"
+
+fi;
+ case "X-$enable_int64" in
+ X-no)
+ echo "$as_me:$LINENO: result: \"disabled\"" >&5
+echo "${ECHO_T}\"disabled\"" >&6
+ SUFFIXES="_32"
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: \"enabled\"" >&5
+echo "${ECHO_T}\"enabled\"" >&6
+ SUFFIXES=""
+ f77int="F77INT64"
+ ;;
+ esac
+ fi
+ ;;
+ *)
+ ;;
+esac
+
+case $host_os in
+ linux*)
+ test x"$linux64" = x"true" && \
+ MACHINE="PCLINUX64${SUFFIXES}" || \
+ MACHINE=PCLINUX
+ ;;
+ hpux*)
+ MACHINE=HP9000
+ ;;
+ aix4.*)
+ MACHINE=RS6000
+ host_os_novers=aix4.x
+ ;;
+ irix5.*)
+ MACHINE="IRIX64${SUFFIXES}"
+ host_os_novers=irix5.x
+ ;;
+ irix6.*)
+ MACHINE="IRIX64${SUFFIXES}"
+ host_os_novers=irix6.x
+ ;;
+ osf4.*)
+ MACHINE="OSF1${SUFFIXES}"
+ host_os_novers=osf4.x
+ ;;
+ osf5.*)
+ MACHINE="OSF1${SUFFIXES}"
+ host_os_novers=osf5.x
+ ;;
+ solaris2.*)
+ MACHINE=SUN4SOL2
+ host_os_novers=solaris2.x
+ ;;
+ uxpv*)
+ MACHINE=VPP5000
+ ;;
+ *)
+ MACHINE=
+ host_os_novers=$host_os
+ ;;
+esac
+
+case $host_cpu in
+ ia64*)
+ MACHINE="PCLINUX64"
+ ;;
+esac
+
+PLATFORM_INCLUDES=" -D$MACHINE "
+
+])dnl
+++ /dev/null
-#
-# PLEASE DO NOT MODIFY configure.in FILE
-#
-# ALL CHANGES WILL BE DISCARDED BY THE NEXT
-# build_configure COMMAND
-#
-# CHANGES MUST BE MADE IN configure.in.base FILE
-#
-#
-# Author : Marc Tajchman (CEA)
-# Date : 28/06/2001
-# Modified by : Patrick GOLDBRONN (CEA)
-# Modified by : Marc Tajchman (CEA)
-#
-# Created from configure.in.base
-#
-
-AC_INIT(src)
-AC_CONFIG_AUX_DIR(${KERNEL_ROOT_DIR}/salome_adm/unix/config_files)
-AC_CANONICAL_HOST
-
-PACKAGE=salome
-AC_SUBST(PACKAGE)
-
-VERSION=4.0.0
-XVERSION=0x040000
-AC_SUBST(VERSION)
-AC_SUBST(XVERSION)
-
-# set up MODULE_NAME variable for dynamic construction of directories (resources, etc.)
-MODULE_NAME=smesh
-AC_SUBST(MODULE_NAME)
-
-dnl
-dnl Initialize source and build root directories
-dnl
-
-ROOT_BUILDDIR=`pwd`
-ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
-cd $ROOT_SRCDIR
-ROOT_SRCDIR=`pwd`
-cd $ROOT_BUILDDIR
-
-AC_SUBST(ROOT_SRCDIR)
-AC_SUBST(ROOT_BUILDDIR)
-
-echo
-echo Source root directory : $ROOT_SRCDIR
-echo Build root directory : $ROOT_BUILDDIR
-echo
-echo
-
-if test -z "$AR"; then
- AC_CHECK_PROGS(AR,ar xar,:,$PATH)
-fi
-AC_SUBST(AR)
-
-dnl Export the AR macro so that it will be placed in the libtool file
-dnl correctly.
-export AR
-
-echo
-echo ---------------------------------------------
-echo testing make
-echo ---------------------------------------------
-echo
-
-AC_PROG_MAKE_SET
-AC_PROG_INSTALL
-dnl
-dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + pour les librairies dynamiques !
-
-AC_ENABLE_DEBUG(yes)
-AC_DISABLE_PRODUCTION
-
-echo ---------------------------------------------
-echo testing libtool
-echo ---------------------------------------------
-
-dnl first, we set static to no!
-dnl if we want it, use --enable-static
-AC_ENABLE_STATIC(no)
-
-AC_LIBTOOL_DLOPEN
-AC_PROG_LIBTOOL
-
-dnl Fix up the INSTALL macro if it s a relative path. We want the
-dnl full-path to the binary instead.
-case "$INSTALL" in
- *install-sh*)
- INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh
- ;;
-esac
-
-echo
-echo ---------------------------------------------
-echo testing C/C++
-echo ---------------------------------------------
-echo
-
-cc_ok=no
-dnl inutil car libtool
-dnl AC_PROG_CC
-AC_PROG_CXX
-AC_DEPEND_FLAG
-# AC_CC_WARNINGS([ansi])
-cc_ok=yes
-
-dnl Library libdl :
-AC_CHECK_LIB(dl,dlopen)
-
-dnl add library libm :
-AC_CHECK_LIB(m,ceil)
-
-dnl
-dnl Well we use sstream which is not in gcc pre-2.95.3
-dnl We must test if it exists. If not, add it in include !
-dnl
-
-AC_CXX_HAVE_SSTREAM
-
-
-
-dnl
-dnl ---------------------------------------------
-dnl testing MPICH
-dnl ---------------------------------------------
-dnl
-
-CHECK_MPICH
-
-echo
-echo ---------------------------------------------
-echo testing LEX \& YACC
-echo ---------------------------------------------
-echo
-
-lex_yacc_ok=no
-AC_PROG_YACC
-AC_PROG_LEX
-lex_yacc_ok=yes
-
-echo
-echo ---------------------------------------------
-echo testing python
-echo ---------------------------------------------
-echo
-
-CHECK_PYTHON
-
-echo
-echo ---------------------------------------------
-echo Testing qwt
-echo ---------------------------------------------
-echo
-
-CHECK_QWT
-
-dnl echo
-dnl echo ---------------------------------------------
-dnl echo testing java
-dnl echo ---------------------------------------------
-dnl echo
-
-dnl CHECK_JAVA
-
-echo
-echo ---------------------------------------------
-echo testing swig
-echo ---------------------------------------------
-echo
-
-CHECK_SWIG
-
-echo
-echo ---------------------------------------------
-echo testing threads
-echo ---------------------------------------------
-echo
-
-ENABLE_PTHREADS
-
-echo
-echo ---------------------------------------------
-echo testing omniORB
-echo ---------------------------------------------
-echo
-
-CHECK_OMNIORB
-
-dnl echo
-dnl echo ---------------------------------------------
-dnl echo testing mico
-dnl echo ---------------------------------------------
-dnl echo
-
-dnl CHECK_MICO
-
-echo
-echo ---------------------------------------------
-echo default ORB : omniORB
-echo ---------------------------------------------
-echo
-
-DEFAULT_ORB=omniORB
-CHECK_CORBA
-
-AC_SUBST_FILE(CORBA)
-corba=make_$ORB
-CORBA=adm_local/unix/$corba
-
-echo
-echo ---------------------------------------------
-echo testing openGL
-echo ---------------------------------------------
-echo
-
-CHECK_OPENGL
-
-echo
-echo ---------------------------------------------
-echo testing QT
-echo ---------------------------------------------
-echo
-
-CHECK_QT
-
-echo
-echo ---------------------------------------------
-echo testing MSG2QM
-echo ---------------------------------------------
-echo
-
-CHECK_MSG2QM
-
-echo
-echo ---------------------------------------------
-echo testing VTK
-echo ---------------------------------------------
-echo
-
-CHECK_VTK
-
-echo
-echo ---------------------------------------------
-echo testing HDF5
-echo ---------------------------------------------
-echo
-
-CHECK_HDF5
-
-echo
-echo ---------------------------------------------
-echo BOOST Library
-echo ---------------------------------------------
-echo
-
-CHECK_BOOST
-
-echo
-echo ---------------------------------------------
-echo Testing OpenCascade
-echo ---------------------------------------------
-echo
-
-CHECK_CAS
-
-echo
-echo ---------------------------------------------
-echo Testing html generators
-echo ---------------------------------------------
-echo
-
-CHECK_HTML_GENERATORS
-
-echo
-echo ---------------------------------------------
-echo Testing GUI
-echo ---------------------------------------------
-echo
-
-CHECK_SALOME_GUI
-
-echo
-echo ---------------------------------------------
-echo Testing full GUI
-echo ---------------------------------------------
-echo
-
-CHECK_CORBA_IN_GUI
-if test "x${CORBA_IN_GUI}" != "xyes"; then
- echo "failed : For configure SMESH module necessary full GUI !"
- exit
-fi
-
-echo
-echo ---------------------------------------------
-echo Testing Kernel
-echo ---------------------------------------------
-echo
-
-CHECK_KERNEL
-
-echo
-echo ---------------------------------------------
-echo Testing Geom
-echo ---------------------------------------------
-echo
-
-CHECK_GEOM
-
-echo
-echo ---------------------------------------------
-echo Testing Med
-echo ---------------------------------------------
-echo
-
-CHECK_MED
-
-echo
-echo ---------------------------------------------
-echo Summary
-echo ---------------------------------------------
-echo
-
-echo Configure
-variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok qwt_ok Kernel_ok Geom_ok Med_ok"
-
-for var in $variables
-do
- printf " %10s : " `echo \$var | sed -e "s,_ok,,"`
- eval echo \$$var
-done
-
-echo
-echo "Default ORB : $DEFAULT_ORB"
-echo
-
-dnl generals files which could be included in every makefile
-
-AC_SUBST_FILE(COMMENCE) COMMENCE=adm_local/unix/make_commence
-AC_SUBST_FILE(CONCLUDE) CONCLUDE=adm_local/unix/make_conclude
-AC_SUBST_FILE(MODULE) MODULE=salome_adm/unix/make_module
-
-dnl les dependences
-AC_SUBST_FILE(DEPEND) DEPEND=salome_adm/unix/depend
-
-dnl We don t need to say when we re entering directories if we re using
-dnl GNU make becuase make does it for us.
-if test "X$GMAKE" = "Xyes"; then
- AC_SUBST(SETX) SETX=":"
-else
- AC_SUBST(SETX) SETX="set -x"
-fi
-
-# make other build directories
-for rep in salome_adm adm_local doc bin/salome include/salome lib${LIB_LOCATION_SUFFIX}/salome share/salome/resources/${MODULE_NAME} idl
-do
-# if test ! -d $rep ; then
-# eval mkdir $rep
-# fi
- $INSTALL -d $rep
-done
-
-echo
-echo ---------------------------------------------
-echo copying resource files, shell scripts, and
-echo xml files
-echo ---------------------------------------------
-echo
-
-
-dnl copy resources directories
-
-#for i in `find $ROOT_SRCDIR -name 'resources' -print`
-#do
-# local_res=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
-# local_res_dir=`echo $local_res | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
-# mkdir -p $local_res_dir
-# cd $local_res_dir
-# ln -fs $i
-# echo $local_res
-# cd $ROOT_BUILDDIR
-#done
-
-dnl copy shells and utilities contained in the bin directory
-dnl excluding .in files (treated in AC-OUTPUT below) and CVS
-dnl directory
-
-mkdir -p bin/salome
-cd bin/salome
-for i in $ROOT_SRCDIR/bin/*
-do
- local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
- case "$local_bin" in
- *.in | *~) ;;
- ./bin/CVS | ./bin/salome) ;;
- *) /usr/bin/install $i .; echo $local_bin ;;
- esac
-done
-cd $ROOT_BUILDDIR
-
-AC_SUBST_FILE(ENVSCRIPT) ENVSCRIPT=salome_adm/unix/envScript
-
-dnl copy xml files to the build tree (lib directory)
-dnl pourquoi ????
-
-#cd lib
-#for i in `find $ROOT_SRCDIR -name "*.xml" -print`
-#do
-# ln -fs $i
-# echo `echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
-#done
-#cd $ROOT_BUILDDIR
-
-
-echo
-echo ---------------------------------------------
-echo generating Makefiles and configure files
-echo ---------------------------------------------
-echo
-
-AC_OUTPUT_COMMANDS([ \
- chmod +x ./bin/* \
-])
-
-## do not delete this line
<style type="text/css">
<!--
img_whs1 { border:none; width:25px; height:24px; border-style:none; }
-p.whs2 { margin-left:40px; }
-img_whs3 { border:none; width:404px; height:413px; border-style:none; }
-ul.whs4 { list-style:disc; }
-p.whs5 { font-weight:bold; }
+p.whs2 { font-weight:normal; }
+p.whs3 { margin-left:40px; }
+img_whs4 { border:none; width:404px; height:413px; border-style:none; }
+ul.whs5 { list-style:disc; }
+p.whs6 { font-weight:bold; }
-->
</style><script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">
<!--
<p>After definition of algorithms and hypotheses a new mesh is listed in
the Object Browser. Right-click on it and select <img src="image28.gif" width="25px" height="24px" border="0" class="img_whs1"> <span
style="font-weight: bold;"><B>Compute</B></span> - the mesh will be automatically
- displayed in the <span style="font-weight: bold;"><B><a href="files/vtk_3d_viewer.htm">VTK
- 3D Viewer</a>.</B></span> Alternatively click<span style="font-weight: bold;"><B>
- Display only</B></span> to hide all other objects at the same time. </p>
+ displayed in the <span style="font-weight: bold;"><B>VTK 3D Viewer.</B></span>
+ Alternatively click<span style="font-weight: bold;"><B> Display only</B></span>
+ to hide all other objects at the same time. </p>
<p> </p>
+<p class="whs2"><span style="font-weight: bold;"><B>VTK 3D
+ Viewer</B></span> is detailly described in the documentation on <span style="font-weight: bold;"><B>GUI
+ module</B></span>.</p>
+
<p>After the mesh has appeared in the Viewer, you can select it with left
mouse click and get
information about it, change its presentation parameters and access to
<p> </p>
-<p class="whs2"><img src="image15.jpg" width="404px" height="413px" border="0" class="img_whs3"></p>
+<p class="whs3"><img src="image15.jpg" width="404px" height="413px" border="0" class="img_whs4"></p>
<p> </p>
-<ul type="disc" class="whs4">
+<ul type="disc" class="whs5">
<li class=kadov-p><p><span style="font-weight: bold;"><B>Erase all</B></span>
- allows
- provides
more detailed information about the mesh. </p></li>
- <li class=kadov-p><p class="whs5"><a href="files/viewing_mesh_info.htm#standard_infos">Standard
+ <li class=kadov-p><p class="whs6"><a href="files/viewing_mesh_info.htm#standard_infos">Standard
Mesh Infos</a> - <span style="font-weight: normal;">provides basic information
about the mesh.</span></p></li>
to display the ID numbers of all meshing elements or nodes composing your
mesh in the viewer.</p></li>
- <li class=kadov-p><p class="whs5"><a href="presentation.htm" style="font-weight: bold;">Display
+ <li class=kadov-p><p class="whs6"><a href="presentation.htm" style="font-weight: bold;">Display
Mode</a> - <span style="font-weight: normal;">allows to select between
Wireframe, Shading and Nodes presentation.</span></p></li>
--- /dev/null
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Building Compounds</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { font-family:'Arial Black' , sans-serif; font-style:italic; }\r
+p.whs2 { margin-left:40px; }\r
+img_whs3 { border:none; width:25px; height:24px; border-style:none; }\r
+p.whs4 { margin-left:80px; }\r
+img_whs5 { border:none; width:420px; height:367px; float:none; border-style:none; }\r
+ul.whs6 { list-style:disc; }\r
+p.whs7 { margin-left:80px; margin-top:0pt; margin-bottom:0pt; }\r
+p.whs8 { margin-top:0pt; margin-bottom:0pt; margin-left:120px; }\r
+p.whs9 { margin-left:80px; margin-top:0pt; margin-bottom:0pt; font-weight:bold; }\r
+p.whs10 { margin-top:0pt; margin-bottom:0pt; font-style:italic; margin-left:24px; }\r
+img_whs11 { border:none; width:245px; height:257px; border-style:none; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript">\r
+<!--\r
+if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))\r
+{\r
+ var strNSS = "<style type='text/css'>";\r
+ strNSS += "p.whs7 {margin-top:1pt;margin-bottom:1pt; }";\r
+ strNSS += "p.whs8 {margin-top:1pt;margin-bottom:1pt; }";\r
+ strNSS += "p.whs9 {margin-top:1pt;margin-bottom:1pt; }";\r
+ strNSS += "p.whs10 {margin-top:1pt;margin-bottom:1pt; }";\r
+ strNSS +="</style>";\r
+ document.write(strNSS);\r
+}\r
+//-->\r
+</script>\r
+<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+ if (innerWidth != origWidth || innerHeight != origHeight)\r
+ location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+ origWidth = innerWidth;\r
+ origHeight = innerHeight;\r
+ onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+ if (window.setRelStartPage)\r
+ {\r
+ addTocInfo("MESH module\nCreating meshes\nBuilding Compounds");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+ }\r
+\r
+\r
+ if (window.setRelStartPage)\r
+ {\r
+ setRelStartPage("index.htm");\r
+\r
+ autoSync(1);\r
+ sendSyncInfo();\r
+ sendAveInfoOut();\r
+ }\r
+\r
+}\r
+else\r
+ if (window.gbIE4)\r
+ document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Building Compounds</h1>\r
+\r
+<p>Compound Mesh is a combination of several meshes.</p>\r
+\r
+<p class="whs1"> To \r
+ Build a compound:</p>\r
+\r
+<p class="whs2">From the <span style="font-weight: bold;"><B>Mesh</B></span> \r
+ menu select <span style="font-weight: bold;"><B>Build Compound</B></span> or \r
+ click <img src="image161.gif" width="25px" height="24px" border="0" class="img_whs3"> button in the toolbar. The following dialog box will \r
+ appear: </p>\r
+\r
+<p class="whs4"><img src="pics/buildcompound.png" x-maintain-ratio="TRUE" width="420px" height="367px" border="0" class="img_whs5"></p>\r
+\r
+<ul type="disc" class="whs6">\r
+ \r
+ <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Name</B></span> \r
+ - allows selecting the name of the resulting <span style="font-weight: bold;"><B>Compound</B></span></p></li>\r
+ \r
+ <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Meshes \r
+ </B></span>- allows selecting the meshes which will be concatenated. They \r
+ can be chosen in the Object Browser while holding <span style="font-weight: bold;"><B>Ctrl</B></span> \r
+ button.</p></li>\r
+ \r
+ <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Processing \r
+ identical groups</B></span> - allows selecting the method of processing the \r
+ namesake existing on the united meshes. They can be either </p></li>\r
+ \r
+ <li class=kadov-p><p class="whs8"><span style="font-weight: bold;"><B>United</B></span> \r
+ - all elements of Group1 \r
+ on Mesh_1 and \r
+ Group1 on Mesh_2 \r
+ become the elements of Group1 \r
+ on the Compound_Mesh, \r
+ or</p></li>\r
+ \r
+ <li class=kadov-p><p class="whs8"><span style="font-weight: bold;"><B>Renamed</B></span> \r
+ - Group1 on \r
+ Mesh_1 becomes \r
+ Group1_1 and \r
+ Group1 on Mesh_2 \r
+ becomes Group1_2. \r
+ See <span style="font-weight: bold;"><B><a href="grouping_elements.htm">Creating \r
+ Groups</a></B></span> for more information about groups. </p></li>\r
+ \r
+ <li class=kadov-p><p class="whs9"><span style="font-weight: normal;">You \r
+ can simply unite meshes or choose to</span> Merge coincident nodes and \r
+ elements, <span style="font-weight: normal;">in which case it is possible \r
+ to define the</span> Tolerance <span style="font-weight: normal;">for \r
+ this operation.</span> </p></li>\r
+</ul>\r
+\r
+<p class="whs10">Example:</p>\r
+\r
+<p class="whs4"><img src="image160.gif" width="245px" height="257px" border="0" class="img_whs11"></p>\r
+\r
+<p> </p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
<!--
img_whs1 { border:none; width:30px; height:30px; float:none; border-style:none; }
ul.whs2 { list-style:disc; }
-ul.whs3 { list-style:circle; }
-table.whs4 { x-cell-content-align:top; width:45.771%; border-spacing:0px; }
-col.whs5 { width:42.826%; }
-col.whs6 { width:57.174%; }
-tr.whs7 { x-cell-content-align:top; }
-td.whs8 { width:42.826%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
-p.whs9 { margin-right:2px; }
-img_whs10 { border:none; width:170px; height:170px; border-style:none; }
-td.whs11 { width:57.174%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
-p.whs12 { margin-right:240px; }
-img_whs13 { border:none; width:182px; height:177px; border-style:none; }
-table.whs14 { x-cell-content-align:top; width:30.595%; border-spacing:0px; }
-col.whs15 { width:50.334%; }
-col.whs16 { width:49.666%; }
-td.whs17 { width:50.334%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
-img_whs18 { border:none; width:119px; height:299px; border-style:none; }
-td.whs19 { width:49.666%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
-img_whs20 { border:none; width:127px; height:298px; border-style:none; }
-h4.whs21 { margin-left:0px; }
-p.whs22 { margin-left:0px; }
+ol.whs3 { list-style:disc; }
+ul.whs4 { list-style:circle; }
+table.whs5 { x-cell-content-align:top; width:45.771%; border-spacing:0px; }
+col.whs6 { width:42.826%; }
+col.whs7 { width:57.174%; }
+tr.whs8 { x-cell-content-align:top; }
+td.whs9 { width:42.826%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
+p.whs10 { margin-right:2px; }
+img_whs11 { border:none; width:170px; height:170px; border-style:none; }
+td.whs12 { width:57.174%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
+p.whs13 { margin-right:240px; }
+img_whs14 { border:none; width:182px; height:177px; border-style:none; }
+table.whs15 { x-cell-content-align:top; width:30.595%; border-spacing:0px; }
+col.whs16 { width:50.334%; }
+col.whs17 { width:49.666%; }
+td.whs18 { width:50.334%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
+img_whs19 { border:none; width:119px; height:299px; border-style:none; }
+td.whs20 { width:49.666%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
+img_whs21 { border:none; width:127px; height:298px; border-style:none; }
+h4.whs22 { margin-left:0px; }
+p.whs23 { margin-left:0px; }
-->
</style><script type="text/javascript" language="JavaScript">
<!--
if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))
{
var strNSS = "<style type='text/css'>";
- strNSS += "h4.whs21 {margin-left:1pt; }";
- strNSS += "p.whs22 {margin-left:1pt; }";
+ strNSS += "h4.whs22 {margin-left:1pt; }";
+ strNSS += "p.whs23 {margin-left:1pt; }";
strNSS +="</style>";
document.write(strNSS);
}
<p> </p>
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
<ul type="disc" class="whs2">
<li style="list-style: circle;"
type=circle
- class=kadov-p><p>Wire Discretization meshing algorithm</p></li>
+ class=kadov-p><p>Wire Discretisation meshing algorithm - splits
+ a wire into a number of mesh segments following any 1D hypothesis.</p></li>
+
+ <li style="list-style: circle;"
+ type=circle
+ class=kadov-p><p>Composite Side Discretisation algorithm -
+ allows to apply any 1D hypothesis to a whole side of a geometrical face
+ even if it is composed of several edges provided that they form C1 curve,
+ have the same hypotheses assigned and form one side in all faces of the
+ main shape of a mesh.</p></li>
</ul>
-</ul>
+</ol>
<p> </p>
<p> </p>
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
- <ul type="circle" class="whs3">
+ <ul type="circle" class="whs4">
<li class=kadov-p><p>Triangle meshing algorithms (Mefisto and Netgen
1D-2D ) - Faces are split into triangular elements.</p></li>
<li class=kadov-p><p>Quadrangle meshing algorithm (Mapping) - Faces
are split into quadrangular elements.</p></li>
</ul>
-</ul>
+</ol>
<p> </p>
-<table x-use-null-cells cellspacing="0" width="45.771%" class="whs4">
-<col class="whs5">
+<table x-use-null-cells cellspacing="0" width="45.771%" class="whs5">
<col class="whs6">
+<col class="whs7">
-<tr valign="top" class="whs7">
-<td width="42.826%" class="whs8">
-<p class="whs9"><img src="../image123.gif" width="170px" height="170px" border="0" class="img_whs10"></td>
-<td width="57.174%" class="whs11">
-<p class="whs12"><img src="../image124.gif" width="182px" height="177px" border="0" class="img_whs13"></td></tr>
+<tr valign="top" class="whs8">
+<td width="42.826%" class="whs9">
+<p class="whs10"><img src="../image123.gif" width="170px" height="170px" border="0" class="img_whs11"></td>
+<td width="57.174%" class="whs12">
+<p class="whs13"><img src="../image124.gif" width="182px" height="177px" border="0" class="img_whs14"></td></tr>
</table>
<p> </p>
<p> </p>
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
- <ul type="circle" class="whs3">
+ <ul type="circle" class="whs4">
<li class=kadov-p><p>Hexahedron meshing algorithm (i,j,k) - Volumes
are split into hexahedral (cubic) elements. </p></li>
<li class=kadov-p><p>Tetrahedron (Netgen) meshing algorithm - Volumes
are split into tetrahedral (pyramidal) elements. </p></li>
</ul>
-</ul>
+</ol>
<p> </p>
-<table x-use-null-cells cellspacing="0" width="30.595%" class="whs14">
-<col class="whs15">
+<table x-use-null-cells cellspacing="0" width="30.595%" class="whs15">
<col class="whs16">
+<col class="whs17">
-<tr valign="top" class="whs7">
-<td width="50.334%" class="whs17">
-<p><img src="../image125.gif" width="119px" height="299px" border="0" class="img_whs18"> </td>
-<td width="49.666%" class="whs19">
-<p><img src="../image126.gif" width="127px" height="298px" border="0" class="img_whs20"></td></tr>
+<tr valign="top" class="whs8">
+<td width="50.334%" class="whs18">
+<p><img src="../image125.gif" width="119px" height="299px" border="0" class="img_whs19"> </td>
+<td width="49.666%" class="whs20">
+<p><img src="../image126.gif" width="127px" height="298px" border="0" class="img_whs21"></td></tr>
</table>
<p> </p>
prismatic shapes.</a> </p></li>
</ul>
-<h4 class="whs21"><a href="constructing_meshes.htm">Constructing
+<h4 class="whs22"><a href="constructing_meshes.htm">Constructing
meshes</a> <span style="font-weight: normal;">page describes in detail
how to apply meshing algorithms.</span><a href="constructing_meshes.htm" style="font-weight: bold;">
</a></h4>
-<p class="whs22"><span style="font-weight: bold;"><B>See Also</B></span>
+<p class="whs23"><span style="font-weight: bold;"><B>See Also</B></span>
a sample TUI Script of a <a href="../defining_hypotheses_tui.htm#bookmark8">Define
Meshing Algorithm</a> operation. </p>
p.whs3 { margin-left:40px; }
img_whs4 { border:none; width:22px; height:24px; border-style:none; }
p.whs5 { margin-left:80px; }
-img_whs6 { border:none; border-style:none; width:355px; height:296px; float:none; }
+img_whs6 { border:none; width:370px; height:296px; float:none; }
img_whs7 { border:none; width:173px; height:88px; border-style:none; }
img_whs8 { border:none; width:34px; height:29px; border-style:none; }
img_whs9 { border:none; width:29px; height:28px; border-style:none; }
<p class="whs3"> </p>
-<p class="whs5"><img src="../pics/createmesh-inv.png" x-maintain-ratio="TRUE" width="355px" height="296px" border="0" class="img_whs6"></p>
+<p class="whs5"><img src="../pics/createmesh-inv.png" x-maintain-ratio="TRUE" width="370px" height="296px" border="0" class="img_whs6"></p>
<p class="whs5"> </p>
p.whs3 { margin-left:40px; }
img_whs4 { border:none; width:27px; height:25px; border-style:none; }
p.whs5 { margin-left:80px; }
-img_whs6 { border:none; border-style:none; width:355px; height:326px; float:none; }
+img_whs6 { border:none; width:370px; height:326px; float:none; }
p.whs7 { margin-left:38px; }
img_whs8 { border:none; width:224px; height:212px; border-style:none; }
-->
<p class="whs3"> </p>
-<p class="whs5"><img src="../pics/createmesh-inv2.png" x-maintain-ratio="TRUE" width="355px" height="326px" border="0" class="img_whs6"></p>
+<p class="whs5"><img src="../pics/createmesh-inv2.png" x-maintain-ratio="TRUE" width="370px" height="326px" border="0" class="img_whs6"></p>
<p class="whs7"> </p>
<!--
img_whs1 { border:none; width:30px; height:30px; float:none; border-style:none; }
p.whs2 { margin-left:40px; }
-img_whs3 { border:none; width:312px; height:488px; float:none; border-style:none; }
+img_whs3 { border:none; width:400px; height:488px; float:none; }
img_whs4 { border:none; width:341px; height:375px; float:none; border-style:none; }
img_whs5 { border:none; float:none; width:347px; height:376px; border-style:none; }
-->
<p> </p>
-<p class="whs2"><img src="../pics/mergenodes.png" x-maintain-ratio="TRUE" width="312px" height="488px" border="0" class="img_whs3"></p>
+<p class="whs2"><img src="../pics/mergenodes.png" x-maintain-ratio="TRUE" width="400px" height="488px" border="0" class="img_whs3"></p>
<p class="whs2"> </p>
</script>
<style type="text/css">
<!--
-img_whs1 { border:none; border-style:none; width:355px; height:296px; float:none; }
+img_whs1 { border:none; width:370px; height:296px; float:none; }
img_whs2 { border:none; width:30px; height:29px; border-style:none; }
p.whs3 { margin-left:40px; }
img_whs4 { border:none; float:none; width:386px; height:336px; border-style:none; }
<p> </p>
<p class=TODO
- style="margin-left: 40px;"><img src="../pics/createmesh-inv3.png" x-maintain-ratio="TRUE" width="355px" height="296px" border="0" class="img_whs1"></p>
+ style="margin-left: 40px;"><img src="../pics/createmesh-inv3.png" x-maintain-ratio="TRUE" width="370px" height="296px" border="0" class="img_whs1"></p>
<p>You can also change values for the current hypothesis by clicking the
<img src="../image122.gif" width="30px" height="29px" border="0" class="img_whs2"> button. </p>
+++ /dev/null
-<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">
-
-<html>
-
-<head>
-<title>VTK 3D Viewer</title>
-<meta http-equiv="content-type" content="text/html; charset=windows-1252">
-<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">
-<!--
-p.whs1 { margin-top:0pt; margin-bottom:0pt; }
-p.whs2 { margin-top:0pt; margin-bottom:0pt; margin-left:48px; }
-img_whs3 { border:none; width:301px; height:26px; float:none; }
-ul.whs4 { list-style:disc; }
-img_whs5 { border:none; width:26px; height:25px; float:none; border-style:none; }
-img_whs6 { border:none; width:27px; height:25px; float:none; border-style:none; }
-img_whs7 { border:none; width:24px; height:23px; float:none; border-style:none; }
-img_whs8 { border:none; width:24px; height:24px; float:none; border-style:none; }
-img_whs9 { border:none; width:25px; height:24px; float:none; border-style:none; }
-img_whs10 { border:none; width:23px; height:23px; float:none; border-style:none; }
-img_whs11 { border:none; width:20px; height:20px; float:none; }
-p.whs12 { margin-top:0pt; margin-bottom:0pt; margin-left:80px; }
-img_whs13 { border:none; width:410px; height:255px; float:none; }
-img_whs14 { border:none; width:26px; height:26px; float:none; border-style:none; }
-img_whs15 { border:none; width:78px; height:147px; float:none; border-style:none; }
-img_whs16 { border:none; width:28px; height:25px; float:none; border-style:none; }
-img_whs17 { border:none; width:27px; height:27px; float:none; border-style:none; }
-p.whs18 { font-weight:bold; margin-left:80px; margin-top:0pt; margin-bottom:0pt; }
-img_whs19 { border:none; width:350px; height:453px; float:none; border-style:none; }
-p.whs20 { font-weight:bold; margin-top:0pt; margin-bottom:0pt; }
-p.whs21 { font-weight:bold; margin-left:36px; margin-top:0pt; margin-bottom:0pt; }
-p.whs22 { font-weight:bold; margin-left:0px; margin-top:0pt; margin-bottom:0pt; }
-p.whs23 { margin-left:0px; font-weight:bold; margin-top:0pt; margin-bottom:0pt; }
--->
-</style><script type="text/javascript" language="JavaScript">
-<!--
-if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))
-{
- var strNSS = "<style type='text/css'>";
- strNSS += "p.whs1 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs2 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs12 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs18 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs20 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs21 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs22 {margin-left:1pt;margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs23 {margin-left:1pt;margin-top:1pt;margin-bottom:1pt; }";
- strNSS +="</style>";
- document.write(strNSS);
-}
-//-->
-</script>
-<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">
-<!--
-function reDo() {
- if (innerWidth != origWidth || innerHeight != origHeight)
- location.reload();
-}
-if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {
- origWidth = innerWidth;
- origHeight = innerHeight;
- onresize = reDo;
-}
-onerror = null;
-//-->
-</script>
-<style type="text/css">
-<!--
-div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }
-p.WebHelpNavBar { text-align:right; }
--->
-</style><script type="text/javascript" language="javascript1.2" src="../whmsg.js"></script>
-<script type="text/javascript" language="javascript" src="../whver.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whproxy.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whutils.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whtopic.js"></script>
-<script type="text/javascript" language="javascript1.2">
-<!--
-if (window.gbWhTopic)
-{
- if (window.setRelStartPage)
- {
- addTocInfo("MESH module\nViewing meshes\nVTK 3D Viewer");
-addButton("show",BTN_IMG,"Show","","","","",0,0,"../whd_show0.gif","../whd_show2.gif","../whd_show1.gif");
-addButton("hide",BTN_IMG,"Hide","","","","",0,0,"../whd_hide0.gif","../whd_hide2.gif","../whd_hide1.gif");
-
- }
-
-
- if (window.setRelStartPage)
- {
- setRelStartPage("../index.htm");
-
- autoSync(1);
- sendSyncInfo();
- sendAveInfoOut();
- }
-
-}
-else
- if (window.gbIE4)
- document.location.reload();
-//-->
-</script>
-</head>
-<body><script type="text/javascript" language="javascript1.2">
-<!--
-if (window.writeIntopicBar)
- writeIntopicBar(4);
-//-->
-</script>
-<h1>VTK 3D Viewer</h1>
-
-<p class="whs1"><span style="font-weight: bold;"><B>VTK
- 3D viewer</B></span> is the default viewer for Mesh Module, allowing to visualize
- meshes. It is also used in Post-Pro module for all 3D presentations except
- for Gauss Points.</p>
-
-<p class="whs1"> </p>
-
-<p class="whs1">The functionalities of
- VTK viewer are available via its Viewer Toolbar. Buttons marked with small
- downward triangles have extended functionality which can be accessed by
- locking on them with left mouse button. </p>
-
-<p class="whs1"> </p>
-
-<p class="whs2"><img src="../pics/image157.gif" x-maintain-ratio="TRUE" width="301px" height="26px" border="0" class="img_whs3"></p>
-
-<ul type="disc" class="whs4">
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image77.gif" x-maintain-ratio="TRUE" width="26px" height="25px" border="0" class="img_whs5"> <span style="font-weight: bold;"><B>Dump View</B></span> - exports
- an object from the viewer in bmp, png, jpg or jpeg image format. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image78.gif" x-maintain-ratio="TRUE" width="27px" height="25px" border="0" class="img_whs6"> <span style="font-weight: bold;"><B>Show/Hide Trihedron</B></span>
- - shows or hides coordinate axes. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image96.gif" x-maintain-ratio="TRUE" width="24px" height="23px" border="0" class="img_whs7"> <span style="font-weight: bold;"><B>Fit
- all - </B></span>allows to select a point to be the center of a scene representing
- all displayed objects in the visible area.<span style="font-weight: bold;">
- <B></B></span></p></li>
-
- <li class=kadov-p><p class="whs1"> <img src="../pics/image97.gif" x-maintain-ratio="TRUE" width="24px" height="24px" border="0" class="img_whs8"> <span style="font-weight: bold;"><B>Fit area</B></span> - resizes
- the view to place in the visible area only the contents of a frame drawn
- with pressed left mouse button.</p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image98.gif" x-maintain-ratio="TRUE" width="25px" height="24px" border="0" class="img_whs9"> <span style="font-weight: bold;"><B>Zoom</B></span> - allows
- to zoom in and out. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image99.gif" x-maintain-ratio="TRUE" width="23px" height="23px" border="0" class="img_whs10"> <span style="font-weight: bold;"><B>Panning</B></span> - if the
- represented objects are greater that the visible area and you don't wish
- to use <span style="font-weight: bold;"><B>Fit all</B></span> functionality,
- click on this button and you'll be able to drag the scene to see its remote
- parts. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image100.gif" x-maintain-ratio="TRUE" width="24px" height="24px" border="0" class="img_whs8"> <span style="font-weight: bold;"><B>Global panning</B></span> -
- represents all displayed objects in the visible area. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/view_rotation_point.png" x-maintain-ratio="TRUE" width="20px" height="20px" border="0" class="img_whs11"> <span style="font-weight: bold;"><B>Change rotation point</B></span>
- - allows to to choose the point around which the rotation is performed</p></li>
-</ul>
-
-<p class="whs12"><img src="../pics/set_rotation_point_dialog1.png" x-maintain-ratio="TRUE" width="410px" height="255px" border="0" class="img_whs13"></p>
-
-<p class="whs12"> </p>
-
-<p class="whs12">By default the rotation point is located
- in the Center of the bounding box of an object. </p>
-
-<p class="whs12"> </p>
-
-<p class="whs12"><img src="../pics/set_rotation_point_dialog2.png" x-maintain-ratio="TRUE" width="410px" height="255px" border="0" class="img_whs13"></p>
-
-<p class="whs12"> </p>
-
-<p class="whs12">Unchecking <span style="font-weight: bold;"><B>Use
- Bounding Box Center</B></span> box allows you to define the coordinates of
- the rotation point manually. </p>
-
-<p class="whs12"> </p>
-
-<p class="whs12"><span style="font-weight: bold;"><B>Set to
- Origin</B></span> button restores the default rotation point coordinates.</p>
-
-<p class="whs12"><span style="font-weight: bold;"><B>Select
- Point from View</B></span> button allows to select the rotation point in the
- 3D Viewer</p>
-
-<ul type="disc" class="whs4">
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image89.gif" x-maintain-ratio="TRUE" width="26px" height="26px" border="0" class="img_whs14"> <span style="font-weight: bold;"><B>Rotation</B></span> - allows
- to rotate the selected object using the mouse. </p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image102.gif" x-maintain-ratio="TRUE" width="78px" height="147px" border="0" class="img_whs15"> These buttons orientate the scene strictly about coordinate
- axes.</p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image91.gif" x-maintain-ratio="TRUE" width="26px" height="26px" border="0" class="img_whs14"> <span style="font-weight: bold;"><B>Reset</B></span> - restores
- the default position (isometric) of objects in the scene.</p></li>
-
- <li class=kadov-p><p class="whs1"><img src="../pics/image108.gif" x-maintain-ratio="TRUE" width="28px" height="25px" border="0" class="img_whs16"> <span style="font-weight: bold;"><B>Scaling</B></span> - represents
- objects deformed (stretched or stuffed) along the axes of coordinates</p></li>
-
- <li class=kadov-p><p class="whs1"> <span
- style="font-weight: bold;
- margin-top: 0pt;
- margin-bottom: 0pt;"><B><img src="../pics/image109.gif" x-maintain-ratio="TRUE" width="27px" height="27px" border="0" class="img_whs17">Graduated axes - </B></span><span style="margin-top: 0pt;
- margin-bottom: 0pt;
- font-weight: normal;">allows
- to define parameters of axes and graduate them.</span></p></li>
-</ul>
-
-<p class="whs1"> </p>
-
-<p class="whs18"><img src="../pics/graduatedaxes1.png" x-maintain-ratio="TRUE" width="350px" height="453px" border="0" class="img_whs19"></p>
-
-<ul type="disc" class="whs4">
-
- <li class=kadov-p><p class="whs20">Axis name </p></li>
-
- <li class=kadov-p><p class="whs21">Is visible - <span
- style="font-weight: normal;">if checked the axis name is displayed in
- the viewer.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Name<span style="font-weight: normal;">
- - allows to redefine the name of the axis.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Font<span style="font-weight: normal;">
- - allows to define color and properties of the font of axis name. </span></p></li>
-
- <li class=kadov-p><p class="whs22">Labels<span style="font-weight: normal;">
- </span></p></li>
-
- <li class=kadov-p><p class="whs21">Is visible - <span
- style="font-weight: normal;">if checked the labels are displayed in the
- viewer.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Number<span style="font-weight: normal;">
- - allows to define the number of labels.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Offset<span style="font-weight: normal;">
- - allows to define the distance between labels.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Font<span style="font-weight: normal;">
- - allows to define color and properties of the font of labels names.</span></p></li>
-
- <li class=kadov-p><p class="whs23">Tick marks </p></li>
-
- <li class=kadov-p><p class="whs21">Is visible - <span
- style="font-weight: normal;">if checked the tick marks are displayed in
- the viewer.</span></p></li>
-
- <li class=kadov-p><p class="whs21">Length<span style="font-weight: normal;">
- - allows to define the length of tick marks</span></p></li>
-
- <li class=kadov-p><p class="whs23">Is visible <span style="font-weight: normal;">if
- checked the axis is displayed in the viewer.</span></p></li>
-</ul>
-
-<script type="text/javascript" language="javascript1.2">
-<!--
-if (window.writeIntopicBar)
- writeIntopicBar(0);
-//-->
-</script>
-</body>
-</html>
--- /dev/null
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Mesh through point</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { font-family:'Arial Black' , sans-serif; font-style:italic; margin-left:0px; }\r
+p.whs2 { margin-left:36px; }\r
+img_whs3 { border:none; width:27px; height:29px; border-style:none; }\r
+img_whs4 { border:none; width:355px; height:366px; float:none; border-style:none; }\r
+p.whs5 { margin-left:40px; font-family:'Times New Roman' , serif; font-style:normal; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript">\r
+<!--\r
+if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))\r
+{\r
+ var strNSS = "<style type='text/css'>";\r
+ strNSS += "p.whs1 {margin-left:1pt; }";\r
+ strNSS +="</style>";\r
+ document.write(strNSS);\r
+}\r
+//-->\r
+</script>\r
+<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+ if (innerWidth != origWidth || innerHeight != origHeight)\r
+ location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+ origWidth = innerWidth;\r
+ origHeight = innerHeight;\r
+ onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+ if (window.setRelStartPage)\r
+ {\r
+ addTocInfo("MESH module\nModifying meshes\nMesh through point");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+ }\r
+\r
+\r
+ if (window.setRelStartPage)\r
+ {\r
+ setRelStartPage("index.htm");\r
+\r
+ autoSync(1);\r
+ sendSyncInfo();\r
+ sendAveInfoOut();\r
+ }\r
+\r
+}\r
+else\r
+ if (window.gbIE4)\r
+ document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Mesh through point</h1>\r
+\r
+<p>In mesh you can define a node at a certain point either by creation \r
+ of a new node, by movement of the node closest to the point or by movement \r
+ of any node to the point.</p>\r
+\r
+<p class="whs1">To create a mesh passing through a point:</p>\r
+\r
+<p class="whs2">1. From the <span style="font-weight: bold;"><B>Modification \r
+ </B></span>menu choose the <span style="font-weight: bold;"><B>Mesh through point \r
+ </B></span>item or click <img src="image159.gif" width="27px" height="29px" border="0" class="img_whs3"> button in the toolbar. The following \r
+ dialog box shall appear:</p>\r
+\r
+<p class="whs2"><img src="pics/meshtopass.png" x-maintain-ratio="TRUE" width="355px" height="366px" border="0" class="img_whs4"></p>\r
+\r
+<p class="whs2">2. Enter the coordinates of the point</p>\r
+\r
+<p class="whs2">3. Choose one of several methods: you can \r
+ either <span style="font-weight: bold;"><B>Create</B></span> a new node at the \r
+ indicated point or Move the existing node to the point. In the latter \r
+ case you can check in <span style="font-weight: bold;"><B>Automatic search</B></span> \r
+ of the closest node or select the necessary node manually. <span style="font-weight: bold;"><B>Preview</B></span> \r
+ check-box allows to see the results of the operation. </p>\r
+\r
+<p class="whs2">4. Click the <span style="font-weight: bold;"><B>Apply \r
+ </B></span>or <span style="font-weight: bold;"><B>OK </B></span>button.</p>\r
+\r
+<p> <span style="font-weight: bold;"><B>See \r
+ Also</B></span> a sample TUI Script of a <a href="modifying_meshes.htm#bookmark14">Mesh \r
+ through point</a> operation. </p>\r
+\r
+<p> </p>\r
+\r
+<p class="whs2"> </p>\r
+\r
+<p> </p>\r
+\r
+<p class="whs5"> </p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
h4.whs4 { margin-top:0pt; margin-bottom:0pt; }
p.whs5 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Lucida Console' , monospace; }
p.whs6 { margin-top:0.5pt; margin-bottom:0pt; }
-p.whs7 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; }
-p.whs8 { font-family:'Lucida Console' , monospace; }
-p.whs9 { font-family:'Times New Roman' , serif; }
-p.whs10 { margin-left:36px; font-family:'Lucida Console' , monospace; }
-p.whs11 { margin-left:36px; }
-p.whs12 { margin-left:0px; font-family:'Times New Roman' , serif; }
-p.whs13 { font-family:'Lucida Console' , monospace; margin-left:0px; }
+p.whs7 { margin-top:0pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; font-weight:bold; font-size:13.5pt; }
+p.whs8 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; }
+p.whs9 { font-family:'Lucida Console' , monospace; }
+p.whs10 { font-family:'Times New Roman' , serif; }
+p.whs11 { margin-left:36px; font-family:'Lucida Console' , monospace; }
+p.whs12 { margin-left:36px; }
+p.whs13 { margin-left:0px; font-family:'Times New Roman' , serif; }
+p.whs14 { font-family:'Lucida Console' , monospace; margin-left:0px; }
-->
</style><script type="text/javascript" language="JavaScript">
<!--
strNSS += "p.whs5 {margin-top:1pt;margin-bottom:1pt; }";
strNSS += "p.whs6 {margin-top:1pt;margin-bottom:1pt; }";
strNSS += "p.whs7 {margin-top:1pt;margin-bottom:1pt; }";
- strNSS += "p.whs12 {margin-left:1pt; }";
+ strNSS += "p.whs8 {margin-top:1pt;margin-bottom:1pt; }";
strNSS += "p.whs13 {margin-left:1pt; }";
+ strNSS += "p.whs14 {margin-left:1pt; }";
strNSS +="</style>";
document.write(strNSS);
}
<p class="whs1">mesh.MoveNode(38,
20., 10., 0.) </p>
+<p class="whs1"> </p>
+
+<p class="whs2"> </p>
+
+<p class="whs7"><a name=bookmark14
+ style="font-weight: bold; font-size: 13.5pt;">Mesh
+ through point</a></p>
+
<p class="whs3"> </p>
+<p class="whs1">from geompy import
+ *</p>
+
+<p class="whs1">from smesh import
+ *</p>
+
+<p class="whs1"> </p>
+
+<p class="whs1">box = MakeBoxDXDYDZ(200,
+ 200, 200)</p>
+
+<p class="whs1"> </p>
+
+<p class="whs1">mesh = Mesh( box
+ )</p>
+
+<p class="whs1">mesh.Segment().AutomaticLength(0.1)</p>
+
+<p class="whs1">mesh.Quadrangle()</p>
+
+<p class="whs1">mesh.Compute()</p>
+
+<p class="whs3"> </p>
+
+<p class="whs3"># find node at (0,0,0)</p>
+
+<p class="whs1">node000 = None</p>
+
+<p class="whs1">for vId in SubShapeAllIDs(
+ box, ShapeType["VERTEX"]):</p>
+
+<p class="whs1"> if
+ node000: break</p>
+
+<p class="whs1"> nodeIds
+ = mesh.GetSubMeshNodesId( vId, True )</p>
+
+<p class="whs1"> for
+ node in nodeIds:</p>
+
+<p class="whs1"> xyz
+ = mesh.GetNodeXYZ( node )</p>
+
+<p class="whs1"> if
+ xyz[0] == 0 and xyz[1] == 0 and xyz[2] == 0 :</p>
+
+<p class="whs1"> node000
+ = node</p>
+
+<p class="whs1"> pass</p>
+
+<p class="whs1"> pass</p>
+
+<p class="whs1"> pass</p>
+
+<p class="whs1">if not node000:</p>
+
+<p class="whs1"> raise
+ "node000 not found"</p>
+
+<p class="whs3"> </p>
+
+<p class="whs3"># find node000 using the
+ tested function </p>
+
+<p class="whs1">n = mesh.FindNodeClosestTo(
+ -1,-1,-1 )</p>
+
+<p class="whs1">if not n == node000:</p>
+
+<p class="whs1"> raise
+ "FindNodeClosestTo() returns " + str( n ) + " != "
+ + str( node000 )</p>
+
+<p class="whs3"> </p>
+
+<p class="whs3"># check if any node will
+ be found for a point inside a box</p>
+
+<p class="whs1">n = mesh.FindNodeClosestTo(
+ 100, 100, 100 )</p>
+
+<p class="whs1">if not n > 0:</p>
+
+<p class="whs1"> raise
+ "FindNodeClosestTo( 100, 100, 100 ) fails"</p>
+
+<p class="whs3"> </p>
+
+<p class="whs3"># move node000 to a new
+ location</p>
+
+<p class="whs1">x,y,z = -10, -10,
+ -10</p>
+
+<p class="whs1">n = mesh.MeshToPassThroughAPoint(
+ x,y,z )</p>
+
+<p class="whs1">if not n == node000:</p>
+
+<p class="whs1"> raise
+ "FindNodeClosestTo() returns " + str( n ) + " != "
+ + str( node000 )</p>
+
+<p class="whs3"> </p>
+
+<p class="whs3"># check the coordinates
+ of the node000</p>
+
+<p class="whs1">xyz = mesh.GetNodeXYZ(
+ node000 )</p>
+
+<p class="whs1">if not ( xyz[0]
+ == x and xyz[1] == y and xyz[2] == z) :</p>
+
+<p class="whs1"> raise
+ "Wrong coordinates: " + str( xyz ) + " != " + str(
+ [x,y,z] )</p>
+
<h3><a name=bookmark4>Diagonal Inversion</a></h3>
<p class="whs5">import salome</p>
<p class="whs5"> </p>
-<p class="whs7"># create an empty mesh
+<p class="whs8"># create an empty mesh
structure</p>
<p class="whs5">mesh = smesh.Mesh()
<p class="whs5"> </p>
-<p class="whs7"># create the following
+<p class="whs8"># create the following
mesh:</p>
<p class="whs5"># .----.----.----.</p>
<p class="whs5"> </p>
-<p class="whs7"># inverse the diagonal
+<p class="whs8"># inverse the diagonal
bb[1] - tt[2]</p>
<p class="whs5">print "\nDiagonal
<h3><a name=bookmark5>Uniting two Triangles</a></h3>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
<p> </p>
<p># create an empty mesh structure</p>
-<p class="whs8">mesh = smesh.Mesh()
+<p class="whs9">mesh = smesh.Mesh()
</p>
<p> </p>
<p># create the following mesh:</p>
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
-<p class="whs8"># | /|
+<p class="whs9"># | /|
/|
/|</p>
-<p class="whs8"># | /
+<p class="whs9"># | /
| / | /
|</p>
-<p class="whs8"># | / |
+<p class="whs9"># | / |
/ | / |</p>
-<p class="whs8"># |/ |/
+<p class="whs9"># |/ |/
|/
|</p>
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
<p> </p>
-<p class="whs8">bb = [0, 0, 0, 0]</p>
+<p class="whs9">bb = [0, 0, 0, 0]</p>
-<p class="whs8">tt = [0, 0, 0, 0]</p>
+<p class="whs9">tt = [0, 0, 0, 0]</p>
-<p class="whs8">ff = [0, 0, 0, 0,
+<p class="whs9">ff = [0, 0, 0, 0,
0, 0]</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">bb[0]
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">bb[0]
= mesh.AddNode( 0., 0., 0.)</span></p>
-<p class="whs8">bb[1] = mesh.AddNode(10.,
+<p class="whs9">bb[1] = mesh.AddNode(10.,
0., 0.)</p>
-<p class="whs8">bb[2] = mesh.AddNode(20.,
+<p class="whs9">bb[2] = mesh.AddNode(20.,
0., 0.)</p>
-<p class="whs8">bb[3] = mesh.AddNode(30.,
+<p class="whs9">bb[3] = mesh.AddNode(30.,
0., 0.)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">tt[0] = mesh.AddNode(
+<p class="whs9">tt[0] = mesh.AddNode(
0., 15., 0.)</p>
-<p class="whs8">tt[1] = mesh.AddNode(10.,
+<p class="whs9">tt[1] = mesh.AddNode(10.,
15., 0.)</p>
-<p class="whs8">tt[2] = mesh.AddNode(20.,
+<p class="whs9">tt[2] = mesh.AddNode(20.,
15., 0.)</p>
-<p class="whs8">tt[3] = mesh.AddNode(30.,
+<p class="whs9">tt[3] = mesh.AddNode(30.,
15., 0.)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">ff[0] = mesh.AddFace([bb[0],
+<p class="whs9">ff[0] = mesh.AddFace([bb[0],
bb[1], tt[1]])</p>
-<p class="whs8">ff[1] = mesh.AddFace([bb[0],
+<p class="whs9">ff[1] = mesh.AddFace([bb[0],
tt[1], tt[0]])</p>
-<p class="whs8">ff[2] = mesh.AddFace([bb[1],
+<p class="whs9">ff[2] = mesh.AddFace([bb[1],
bb[2], tt[2]])</p>
-<p class="whs8">ff[3] = mesh.AddFace([bb[1],
+<p class="whs9">ff[3] = mesh.AddFace([bb[1],
tt[2], tt[1]])</p>
-<p class="whs8">ff[4] = mesh.AddFace([bb[2],
+<p class="whs9">ff[4] = mesh.AddFace([bb[2],
bb[3], tt[3]])</p>
-<p class="whs8">ff[5] = mesh.AddFace([bb[2],
+<p class="whs9">ff[5] = mesh.AddFace([bb[2],
tt[3], tt[2]]) </p>
<p> </p>
<p># delete the diagonal bb[1] - tt[2]</p>
-<p class="whs8">print "\nUnite
+<p class="whs9">print "\nUnite
two triangles ... ",</p>
-<p class="whs8">res = mesh.DeleteDiag(bb[1],
+<p class="whs9">res = mesh.DeleteDiag(bb[1],
tt[2])</p>
-<p class="whs8">if not res: print
+<p class="whs9">if not res: print
"failed!"</p>
-<p class="whs8">else: print
+<p class="whs9">else: print
"done."</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
<p><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span>
</p>
<h3><a name=bookmark6>Uniting a Set of Triangles</a></h3>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># create an empty mesh
+<p class="whs10"># create an empty mesh
structure</p>
-<p class="whs8">mesh = smesh.Mesh()
+<p class="whs9">mesh = smesh.Mesh()
</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># create the following
+<p class="whs10"># create the following
mesh:</p>
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
-<p class="whs8"># | /|
+<p class="whs9"># | /|
/|
/|</p>
-<p class="whs8"># | /
+<p class="whs9"># | /
| / | /
|</p>
-<p class="whs8"># | / |
+<p class="whs9"># | / |
/ | / |</p>
-<p class="whs8"># |/ |/
+<p class="whs9"># |/ |/
|/
|</p>
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">bb = [0, 0, 0, 0]</p>
+<p class="whs9">bb = [0, 0, 0, 0]</p>
-<p class="whs8">tt = [0, 0, 0, 0]</p>
+<p class="whs9">tt = [0, 0, 0, 0]</p>
-<p class="whs8">ff = [0, 0, 0, 0,
+<p class="whs9">ff = [0, 0, 0, 0,
0, 0]</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">bb[0]
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">bb[0]
= mesh.AddNode( 0., 0., 0.)</span></p>
-<p class="whs8">bb[1] = mesh.AddNode(10.,
+<p class="whs9">bb[1] = mesh.AddNode(10.,
0., 0.)</p>
-<p class="whs8">bb[2] = mesh.AddNode(20.,
+<p class="whs9">bb[2] = mesh.AddNode(20.,
0., 0.)</p>
-<p class="whs8">bb[3] = mesh.AddNode(30.,
+<p class="whs9">bb[3] = mesh.AddNode(30.,
0., 0.)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">tt[0] = mesh.AddNode(
+<p class="whs9">tt[0] = mesh.AddNode(
0., 15., 0.)</p>
-<p class="whs8">tt[1] = mesh.AddNode(10.,
+<p class="whs9">tt[1] = mesh.AddNode(10.,
15., 0.)</p>
-<p class="whs8">tt[2] = mesh.AddNode(20.,
+<p class="whs9">tt[2] = mesh.AddNode(20.,
15., 0.)</p>
-<p class="whs8">tt[3] = mesh.AddNode(30.,
+<p class="whs9">tt[3] = mesh.AddNode(30.,
15., 0.)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">ff[0] = mesh.AddFace([bb[0],
+<p class="whs9">ff[0] = mesh.AddFace([bb[0],
bb[1], tt[1]])</p>
-<p class="whs8">ff[1] = mesh.AddFace([bb[0],
+<p class="whs9">ff[1] = mesh.AddFace([bb[0],
tt[1], tt[0]])</p>
-<p class="whs8">ff[2] = mesh.AddFace([bb[1],
+<p class="whs9">ff[2] = mesh.AddFace([bb[1],
bb[2], tt[2]])</p>
-<p class="whs8">ff[3] = mesh.AddFace([bb[1],
+<p class="whs9">ff[3] = mesh.AddFace([bb[1],
tt[2], tt[1]])</p>
-<p class="whs8">ff[4] = mesh.AddFace([bb[2],
+<p class="whs9">ff[4] = mesh.AddFace([bb[2],
bb[3], tt[3]])</p>
-<p class="whs8">ff[5] = mesh.AddFace([bb[2],
+<p class="whs9">ff[5] = mesh.AddFace([bb[2],
tt[3], tt[2]])</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># unite a set of triangles</p>
+<p class="whs10"># unite a set of triangles</p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">print
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">print
"\nUnite a set of triangles ... ",</span></p>
-<p class="whs8">res = mesh.TriToQuad([ff[2],
+<p class="whs9">res = mesh.TriToQuad([ff[2],
ff[3], ff[4], ff[5]], smesh.FT_MinimumAngle, 60.)</p>
-<p class="whs8">if not res: print
+<p class="whs9">if not res: print
"failed!"</p>
-<p class="whs8">else: print
+<p class="whs9">else: print
"done."</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">salome.sg.updateObjBrowser(1)
+<p class="whs9">salome.sg.updateObjBrowser(1)
</p>
<h3><a name=bookmark12>Orientation</a></h3>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
<p># create an empty mesh structure</p>
-<p class="whs8">mesh = smesh.Mesh()
+<p class="whs9">mesh = smesh.Mesh()
</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># build five quadrangles:</p>
+<p class="whs10"># build five quadrangles:</p>
-<p class="whs8">dx = 10</p>
+<p class="whs9">dx = 10</p>
-<p class="whs8">dy = 20</p>
+<p class="whs9">dy = 20</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">n1
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">n1
= mesh.AddNode(0.0
* dx, 0, 0)</span></p>
-<p class="whs8">n2 =
+<p class="whs9">n2 =
mesh.AddNode(1.0 * dx, 0, 0)</p>
-<p class="whs8">n3 =
+<p class="whs9">n3 =
mesh.AddNode(2.0 * dx, 0, 0)</p>
-<p class="whs8">n4 =
+<p class="whs9">n4 =
mesh.AddNode(3.0 * dx, 0, 0)</p>
-<p class="whs8">n5 =
+<p class="whs9">n5 =
mesh.AddNode(4.0 * dx, 0, 0)</p>
-<p class="whs8">n6 =
+<p class="whs9">n6 =
mesh.AddNode(5.0 * dx, 0, 0)</p>
-<p class="whs8">n7 =
+<p class="whs9">n7 =
mesh.AddNode(0.0 * dx, dy, 0)</p>
-<p class="whs8">n8 =
+<p class="whs9">n8 =
mesh.AddNode(1.0 * dx, dy, 0)</p>
-<p class="whs8">n9 =
+<p class="whs9">n9 =
mesh.AddNode(2.0 * dx, dy, 0)</p>
-<p class="whs8">n10 = mesh.AddNode(3.0
+<p class="whs9">n10 = mesh.AddNode(3.0
* dx, dy, 0)</p>
-<p class="whs8">n11 = mesh.AddNode(4.0
+<p class="whs9">n11 = mesh.AddNode(4.0
* dx, dy, 0)</p>
-<p class="whs8">n12 = mesh.AddNode(5.0
+<p class="whs9">n12 = mesh.AddNode(5.0
* dx, dy, 0)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">f1 = mesh.AddFace([n1,
+<p class="whs9">f1 = mesh.AddFace([n1,
n2, n8 , n7 ])</p>
-<p class="whs8">f2 = mesh.AddFace([n2,
+<p class="whs9">f2 = mesh.AddFace([n2,
n3, n9 , n8 ])</p>
-<p class="whs8">f3 = mesh.AddFace([n3,
+<p class="whs9">f3 = mesh.AddFace([n3,
n4, n10, n9 ])</p>
-<p class="whs8">f4 = mesh.AddFace([n4,
+<p class="whs9">f4 = mesh.AddFace([n4,
n5, n11, n10])</p>
-<p class="whs8">f5 = mesh.AddFace([n5,
+<p class="whs9">f5 = mesh.AddFace([n5,
n6, n12, n11]) </p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># Change the orientation
+<p class="whs10"># Change the orientation
of the second and the fourth faces.</p>
-<p class="whs8">mesh.Reorient([2,
+<p class="whs9">mesh.Reorient([2,
4])</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">salome.sg.updateObjBrowser(1)
+<p class="whs9">salome.sg.updateObjBrowser(1)
</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
<h3><a name=bookmark7>Cutting Quadrangles</a></h3>
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">smesh = SMESH_mechanic.smesh</p>
+<p class="whs9">smesh = SMESH_mechanic.smesh</p>
-<p class="whs8">mesh =
+<p class="whs9">mesh =
SMESH_mechanic.mesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># cut two quadrangles:
+<p class="whs10"># cut two quadrangles:
405 and 406</p>
-<p class="whs8">mesh.QuadToTri([405,
+<p class="whs9">mesh.QuadToTri([405,
406], smesh.FT_MinimumAngle) </p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
<h3><a name=bookmark8>Smoothing</a></h3>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">smesh
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">smesh
= SMESH_mechanic.smesh</span></p>
-<p class="whs8">mesh = SMESH_mechanic.mesh</p>
+<p class="whs9">mesh = SMESH_mechanic.mesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># select the top face</p>
+<p class="whs10"># select the top face</p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">faces
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">faces
= geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, geompy.ShapeType["FACE"])</span></p>
-<p class="whs8">face = faces[3]</p>
+<p class="whs9">face = faces[3]</p>
-<p class="whs8">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh,
+<p class="whs9">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh,
face, "face planar with hole")</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># create a group of
+<p class="whs9"># create a group of
faces to be smoothed</p>
-<p class="whs8">GroupSmooth = mesh.GroupOnGeom(face,
+<p class="whs9">GroupSmooth = mesh.GroupOnGeom(face,
"Group of faces (smooth)", smesh.FACE)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># perform smoothing</p>
+<p class="whs9"># perform smoothing</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># boolean SmoothObject(Object,
+<p class="whs9"># boolean SmoothObject(Object,
IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method)</p>
-<p class="whs8">res = mesh.SmoothObject(GroupSmooth,
+<p class="whs9">res = mesh.SmoothObject(GroupSmooth,
[], 20, 2., smesh.CENTROIDAL_SMOOTH)</p>
-<p class="whs8">print "\nSmoothing
+<p class="whs9">print "\nSmoothing
... ",</p>
-<p class="whs8">if not res: print
+<p class="whs9">if not res: print
"failed!"</p>
-<p class="whs8">else: print
+<p class="whs9">else: print
"done."</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">salome.sg.updateObjBrowser(1)
+<p class="whs9">salome.sg.updateObjBrowser(1)
</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
<h3><a name=bookmark9>Extrusion</a></h3>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">smesh
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">smesh
= SMESH_mechanic.smesh</span></p>
-<p class="whs8">mesh = SMESH_mechanic.mesh
+<p class="whs9">mesh = SMESH_mechanic.mesh
</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># select the top face</p>
+<p class="whs10"># select the top face</p>
-<p class="whs8">faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh,
+<p class="whs9">faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh,
geompy.ShapeType["FACE"])</p>
-<p class="whs8">face = faces[7]</p>
+<p class="whs9">face = faces[7]</p>
-<p class="whs8">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh,
+<p class="whs9">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh,
face, "face circular top")</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># create a vector
+<p class="whs9"># create a vector
for extrusion</p>
-<p class="whs8">point = smesh.PointStruct(0.,
+<p class="whs9">point = smesh.PointStruct(0.,
0., 5.)</p>
-<p class="whs8">vector = smesh.DirStruct(point)</p>
+<p class="whs9">vector = smesh.DirStruct(point)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># create a group to
+<p class="whs9"># create a group to
be extruded</p>
-<p class="whs8">GroupTri = mesh.GroupOnGeom(face,
+<p class="whs9">GroupTri = mesh.GroupOnGeom(face,
"Group of faces (extrusion)", smesh.FACE)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># perform extrusion
+<p class="whs9"># perform extrusion
of the group</p>
-<p class="whs8">mesh.ExtrusionSweepObject(GroupTri,
+<p class="whs9">mesh.ExtrusionSweepObject(GroupTri,
vector, 5)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span>
+<p class="whs10"><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span>
</p>
<h3><a name=bookmark10>Extrusion along a Path</a></h3>
-<p class="whs8">import math</p>
+<p class="whs9">import math</p>
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># Geometry</p>
+<p class="whs10"># Geometry</p>
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9"># 1. Create points</p>
+<p class="whs10"># 1. Create points</p>
-<p class="whs8">points = [[0, 0],
+<p class="whs9">points = [[0, 0],
[50, 30], [50, 110], [0, 150], [-80, 150], [-130, 70], [-130, -20]]</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">iv = 1</p>
+<p class="whs9">iv = 1</p>
-<p class="whs8">vertices = []</p>
+<p class="whs9">vertices = []</p>
-<p class="whs8">for point in points:</p>
+<p class="whs9">for point in points:</p>
-<p class="whs10">vert
+<p class="whs11">vert
= geompy.MakeVertex(point[0], point[1], 0)</p>
-<p class="whs10">geompy.addToStudy(vert,
+<p class="whs11">geompy.addToStudy(vert,
"Vertex_" + `iv`)</p>
-<p class="whs10">vertices.append(vert)</p>
+<p class="whs11">vertices.append(vert)</p>
-<p class="whs10">iv
+<p class="whs11">iv
+= 1</p>
-<p class="whs10">pass</p>
+<p class="whs11">pass</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9"># 2. Create edges and
+<p class="whs10"># 2. Create edges and
wires</p>
-<p class="whs8">Edge_straight = geompy.MakeEdge(vertices[0],
+<p class="whs9">Edge_straight = geompy.MakeEdge(vertices[0],
vertices[4])</p>
-<p class="whs8">Edge_bezierrr = geompy.MakeBezier(vertices)</p>
+<p class="whs9">Edge_bezierrr = geompy.MakeBezier(vertices)</p>
-<p class="whs8">Wire_polyline = geompy.MakePolyline(vertices)</p>
+<p class="whs9">Wire_polyline = geompy.MakePolyline(vertices)</p>
-<p class="whs8">Edge_Circle =
+<p class="whs9">Edge_Circle =
geompy.MakeCircleThreePnt(vertices[0], vertices[1], vertices[2])</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">geompy.addToStudy(Edge_straight,
+<p class="whs9">geompy.addToStudy(Edge_straight,
"Edge_straight")</p>
-<p class="whs8">geompy.addToStudy(Edge_bezierrr,
+<p class="whs9">geompy.addToStudy(Edge_bezierrr,
"Edge_bezierrr")</p>
-<p class="whs8">geompy.addToStudy(Wire_polyline,
+<p class="whs9">geompy.addToStudy(Wire_polyline,
"Wire_polyline")</p>
-<p class="whs8">geompy.addToStudy(Edge_Circle
+<p class="whs9">geompy.addToStudy(Edge_Circle
, "Edge_Circle")</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9"># 3. Explode wire on
+<p class="whs10"># 3. Explode wire on
edges, as they will be used for mesh extrusion</p>
-<p class="whs8">Wire_polyline_edges
+<p class="whs9">Wire_polyline_edges
= geompy.SubShapeAll(Wire_polyline, geompy.ShapeType["EDGE"])</p>
-<p class="whs8">for ii in range(len(Wire_polyline_edges)):</p>
+<p class="whs9">for ii in range(len(Wire_polyline_edges)):</p>
-<p class="whs10">geompy.addToStudyInFather(Wire_polyline,
+<p class="whs11">geompy.addToStudyInFather(Wire_polyline,
Wire_polyline_edges[ii], "Edge_" + `ii + 1`)</p>
-<p class="whs10">pass</p>
+<p class="whs11">pass</p>
-<p class="whs11"> </p>
+<p class="whs12"> </p>
-<p class="whs9"># Mesh</p>
+<p class="whs10"># Mesh</p>
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs12"># Mesh
+<p class="whs13"># Mesh
the given shape with the given 1d hypothesis</p>
-<p class="whs13">def
+<p class="whs14">def
Mesh1D(shape1d, nbSeg, name):</p>
-<p class="whs13"> mesh1d_tool
+<p class="whs14"> mesh1d_tool
= smesh.Mesh(shape1d, name)</p>
-<p class="whs13"> algo
+<p class="whs14"> algo
= mesh1d_tool.Segment()</p>
-<p class="whs13"> hyp
+<p class="whs14"> hyp
= algo.NumberOfSegments(nbSeg)</p>
-<p class="whs13"> isDone
+<p class="whs14"> isDone
= mesh1d_tool.Compute()</p>
-<p class="whs13"> if
+<p class="whs14"> if
not isDone: print 'Mesh ', name, ': computation failed'</p>
-<p class="whs13"> return
+<p class="whs14"> return
mesh1d_tool</p>
-<p class="whs12"># Create
+<p class="whs13"># Create
a mesh with six nodes, seven edges and two quadrangle faces</p>
-<p class="whs13">def
+<p class="whs14">def
MakeQuadMesh2(mesh_name):</p>
-<p class="whs13"> quad_1
+<p class="whs14"> quad_1
= smesh.Mesh(name = mesh_name)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs13"> <span
+<p class="whs14"> <span
style="font-family: 'Times New Roman', serif;">#
six nodes</span></p>
-<p class="whs13"> n1
+<p class="whs14"> n1
= quad_1.AddNode(0, 20, 10)</p>
-<p class="whs13"> n2
+<p class="whs14"> n2
= quad_1.AddNode(0, 40, 10)</p>
-<p class="whs13"> n3
+<p class="whs14"> n3
= quad_1.AddNode(0, 40, 30)</p>
-<p class="whs13"> n4
+<p class="whs14"> n4
= quad_1.AddNode(0, 20, 30)</p>
-<p class="whs13"> n5
+<p class="whs14"> n5
= quad_1.AddNode(0, 0,
30)</p>
-<p class="whs13"> n6
+<p class="whs14"> n6
= quad_1.AddNode(0, 0,
10)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs13"> <span
+<p class="whs14"> <span
style="font-family: 'Times New Roman', serif;">#
seven edges</span></p>
-<p class="whs13"> quad_1.AddEdge([n1,
+<p class="whs14"> quad_1.AddEdge([n1,
n2]) # 1</p>
-<p class="whs13"> quad_1.AddEdge([n2,
+<p class="whs14"> quad_1.AddEdge([n2,
n3]) # 2</p>
-<p class="whs13"> quad_1.AddEdge([n3,
+<p class="whs14"> quad_1.AddEdge([n3,
n4]) # 3</p>
-<p class="whs13"> quad_1.AddEdge([n4,
+<p class="whs14"> quad_1.AddEdge([n4,
n1]) # 4</p>
-<p class="whs13"> quad_1.AddEdge([n4,
+<p class="whs14"> quad_1.AddEdge([n4,
n5]) # 5</p>
-<p class="whs13"> quad_1.AddEdge([n5,
+<p class="whs14"> quad_1.AddEdge([n5,
n6]) # 6</p>
-<p class="whs13"> quad_1.AddEdge([n6,
+<p class="whs14"> quad_1.AddEdge([n6,
n1]) # 7</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs13"> <span
+<p class="whs14"> <span
style="font-family: 'Times New Roman', serif;">#
two quadrangle faces</span></p>
-<p class="whs13"> quad_1.AddFace([n1,
+<p class="whs14"> quad_1.AddFace([n1,
n2, n3, n4]) # 8</p>
-<p class="whs13"> quad_1.AddFace([n1,
+<p class="whs14"> quad_1.AddFace([n1,
n4, n5, n6]) # 9</p>
-<p class="whs13"> return
+<p class="whs14"> return
[quad_1, [1,2,3,4,5,6,7], [8,9]]</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># Path
+<p class="whs13"># Path
meshes</p>
-<p class="whs13">Edge_straight_mesh
+<p class="whs14">Edge_straight_mesh
= Mesh1D(Edge_straight, 7, "Edge_straight")</p>
-<p class="whs13">Edge_bezierrr_mesh
+<p class="whs14">Edge_bezierrr_mesh
= Mesh1D(Edge_bezierrr, 7, "Edge_bezierrr")</p>
-<p class="whs13">Wire_polyline_mesh
+<p class="whs14">Wire_polyline_mesh
= Mesh1D(Wire_polyline, 3, "Wire_polyline")</p>
-<p class="whs13">Edge_Circle_mesh
+<p class="whs14">Edge_Circle_mesh
=
Mesh1D(Edge_Circle ,
8, "Edge_Circle")</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># Initial
+<p class="whs13"># Initial
meshes (to be extruded)</p>
-<p class="whs13">[quad_1,
+<p class="whs14">[quad_1,
ee_1, ff_1] = MakeQuadMesh2("quad_1")</p>
-<p class="whs13">[quad_2,
+<p class="whs14">[quad_2,
ee_2, ff_2] = MakeQuadMesh2("quad_2")</p>
-<p class="whs13">[quad_3,
+<p class="whs14">[quad_3,
ee_3, ff_3] = MakeQuadMesh2("quad_3")</p>
-<p class="whs13">[quad_4,
+<p class="whs14">[quad_4,
ee_4, ff_4] = MakeQuadMesh2("quad_4")</p>
-<p class="whs13">[quad_5,
+<p class="whs14">[quad_5,
ee_5, ff_5] = MakeQuadMesh2("quad_5")</p>
-<p class="whs13">[quad_6,
+<p class="whs14">[quad_6,
ee_6, ff_6] = MakeQuadMesh2("quad_6")</p>
-<p class="whs13">[quad_7,
+<p class="whs14">[quad_7,
ee_7, ff_7] = MakeQuadMesh2("quad_7")</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># ExtrusionAlongPath</p>
+<p class="whs13"># ExtrusionAlongPath</p>
-<p class="whs12"># IDsOfElements,
+<p class="whs13"># IDsOfElements,
PathMesh, PathShape, NodeStart,</p>
-<p class="whs12"># HasAngles,
+<p class="whs13"># HasAngles,
Angles, HasRefPoint, RefPoint</p>
-<p class="whs13">refPoint
+<p class="whs14">refPoint
= smesh.PointStruct(0, 0, 0)</p>
-<p class="whs13">a10
+<p class="whs14">a10
= 10.0*math.pi/180.0</p>
-<p class="whs13">a45
+<p class="whs14">a45
= 45.0*math.pi/180.0</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 1.
+<p class="whs13"># 1.
Extrusion of two mesh edges along a straight path</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_1.ExtrusionAlongPath([1,2], Edge_straight_mesh, Edge_straight,
1,</p>
-<p class="whs13"> 0,
+<p class="whs14"> 0,
[], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 2.
+<p class="whs13"># 2.
Extrusion of one mesh edge along a curved path</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_2.ExtrusionAlongPath([2], Edge_bezierrr_mesh, Edge_bezierrr, 1,</p>
-<p class="whs13"> 0,
+<p class="whs14"> 0,
[], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 3.
+<p class="whs13"># 3.
Extrusion of one mesh edge along a curved path with usage of angles</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_3.ExtrusionAlongPath([2], Edge_bezierrr_mesh, Edge_bezierrr, 1,</p>
-<p class="whs13"> 1,
+<p class="whs14"> 1,
[a45, a45, a45, 0, -a45, -a45, -a45], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 4.
+<p class="whs13"># 4.
Extrusion of one mesh edge along the path, which is a part of a meshed
wire</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_4.ExtrusionAlongPath([4], Wire_polyline_mesh, Wire_polyline_edges[0],
1,</p>
-<p class="whs13"> 1,
+<p class="whs14"> 1,
[a10, a10, a10], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 5.
+<p class="whs13"># 5.
Extrusion of two mesh faces along the path, which is a part of a meshed
wire</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_5.ExtrusionAlongPath(ff_5 , Wire_polyline_mesh, Wire_polyline_edges[2],
4,</p>
-<p class="whs13"> 0,
+<p class="whs14"> 0,
[], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 6.
+<p class="whs13"># 6.
Extrusion of two mesh faces along a closed path</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_6.ExtrusionAlongPath(ff_6 , Edge_Circle_mesh, Edge_Circle, 1,</p>
-<p class="whs13"> 0,
+<p class="whs14"> 0,
[], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs12"># 7.
+<p class="whs13"># 7.
Extrusion of two mesh faces along a closed path with usage of angles</p>
-<p class="whs13">error
+<p class="whs14">error
= quad_7.ExtrusionAlongPath(ff_7, Edge_Circle_mesh, Edge_Circle, 1,</p>
-<p class="whs13"> 1,
+<p class="whs14"> 1,
[a45, -a45, a45, -a45, a45, -a45, a45, -a45], 0, refPoint)</p>
-<p class="whs13"> </p>
+<p class="whs14"> </p>
-<p class="whs13">salome.sg.updateObjBrowser(1)
+<p class="whs14">salome.sg.updateObjBrowser(1)
</p>
<h3><a name=bookmark11>Revolution</a></h3>
-<p class="whs8">import math</p>
+<p class="whs9">import math</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">mesh
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">mesh
= SMESH_mechanic.mesh</span></p>
-<p class="whs8">smesh = SMESH_mechanic.smesh</p>
+<p class="whs9">smesh = SMESH_mechanic.smesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># create a group of faces
+<p class="whs10"># create a group of faces
to be revolved</p>
-<p class="whs8">FacesRotate = [492,
+<p class="whs9">FacesRotate = [492,
493, 502, 503]</p>
-<p class="whs8">GroupRotate = mesh.CreateGroup(SMESH.FACE,"Group
+<p class="whs9">GroupRotate = mesh.CreateGroup(SMESH.FACE,"Group
of faces (rotate)")</p>
-<p class="whs8">GroupRotate.Add(FacesRotate)</p>
+<p class="whs9">GroupRotate.Add(FacesRotate)</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9"># define revolution angle
+<p class="whs10"># define revolution angle
and axis</p>
-<p class="whs8">angle45 = 45 * math.pi
+<p class="whs9">angle45 = 45 * math.pi
/ 180</p>
-<p class="whs8">axisXYZ = SMESH.AxisStruct(-38.3128,
+<p class="whs9">axisXYZ = SMESH.AxisStruct(-38.3128,
-73.3658, -23.321, -13.3402, -13.3265, 6.66632)</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs9"># perform revolution
+<p class="whs10"># perform revolution
of an object</p>
-<p class="whs8">mesh.RotationSweepObject(GroupRotate,
+<p class="whs9">mesh.RotationSweepObject(GroupRotate,
axisXYZ, angle45, 4, 1e-5) </p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
<h3><a name=bookmark13>Pattern Mapping</a></h3>
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
-<p class="whs8"> </p>
+<p class="whs9"> </p>
-<p class="whs8"># define the geometry</p>
+<p class="whs9"># define the geometry</p>
-<p class="whs9">Box_1 = geompy.MakeBoxDXDYDZ(200.,
+<p class="whs10">Box_1 = geompy.MakeBoxDXDYDZ(200.,
200., 200.)</p>
-<p class="whs9">geompy.addToStudy(Box_1,
+<p class="whs10">geompy.addToStudy(Box_1,
"Box_1")</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">faces = geompy.SubShapeAll(Box_1,
+<p class="whs10">faces = geompy.SubShapeAll(Box_1,
geompy.ShapeType["FACE"])</p>
-<p class="whs9">Face_1 = faces[0]</p>
+<p class="whs10">Face_1 = faces[0]</p>
-<p class="whs9">Face_2 = faces[1]</p>
+<p class="whs10">Face_2 = faces[1]</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">geompy.addToStudyInFather(Box_1,
+<p class="whs10">geompy.addToStudyInFather(Box_1,
Face_1, "Face_1")</p>
-<p class="whs9">geompy.addToStudyInFather(Box_1,
+<p class="whs10">geompy.addToStudyInFather(Box_1,
Face_2, "Face_2")</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs8"># build a quadrangle
+<p class="whs9"># build a quadrangle
mesh 3x3 on Face_1</p>
-<p class="whs9">Mesh_1 = smesh.Mesh(Face_1)</p>
+<p class="whs10">Mesh_1 = smesh.Mesh(Face_1)</p>
-<p class="whs9">algo1D = Mesh_1.Segment()</p>
+<p class="whs10">algo1D = Mesh_1.Segment()</p>
-<p class="whs9">algo1D.NumberOfSegments(3)</p>
+<p class="whs10">algo1D.NumberOfSegments(3)</p>
-<p class="whs9">Mesh_1.Quadrangle()</p>
+<p class="whs10">Mesh_1.Quadrangle()</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">isDone = Mesh_1.Compute()</p>
+<p class="whs10">isDone = Mesh_1.Compute()</p>
-<p class="whs9">if not isDone: print
+<p class="whs10">if not isDone: print
'Mesh Mesh_1 : computation failed'</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs8"># build a triangle
+<p class="whs9"># build a triangle
mesh on Face_2</p>
-<p class="whs9">Mesh_2 = smesh.Mesh(Face_2)</p>
+<p class="whs10">Mesh_2 = smesh.Mesh(Face_2)</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">algo1D = Mesh_2.Segment()</p>
+<p class="whs10">algo1D = Mesh_2.Segment()</p>
-<p class="whs9">algo1D.NumberOfSegments(1)</p>
+<p class="whs10">algo1D.NumberOfSegments(1)</p>
-<p class="whs9">algo2D = Mesh_2.Triangle()</p>
+<p class="whs10">algo2D = Mesh_2.Triangle()</p>
-<p class="whs9">algo2D.MaxElementArea(240)</p>
+<p class="whs10">algo2D.MaxElementArea(240)</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">isDone = Mesh_2.Compute()</p>
+<p class="whs10">isDone = Mesh_2.Compute()</p>
-<p class="whs9">if not isDone: print
+<p class="whs10">if not isDone: print
'Mesh Mesh_2 : computation failed'</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs8"># create a pattern</p>
+<p class="whs9"># create a pattern</p>
-<p class="whs9">pattern = smesh.GetPattern()</p>
+<p class="whs10">pattern = smesh.GetPattern()</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">isDone = pattern.LoadFromFace(Mesh_2.GetMesh(),
+<p class="whs10">isDone = pattern.LoadFromFace(Mesh_2.GetMesh(),
Face_2, 0)</p>
-<p class="whs9">if (isDone != 1): print
+<p class="whs10">if (isDone != 1): print
'LoadFromFace :', pattern.GetErrorCode()</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs8"># apply the pattern
+<p class="whs9"># apply the pattern
to a face of the first mesh</p>
-<p class="whs9">pattern.ApplyToMeshFaces(Mesh_1.GetMesh(),
+<p class="whs10">pattern.ApplyToMeshFaces(Mesh_1.GetMesh(),
[17], 0, 0)</p>
-<p class="whs9"> </p>
+<p class="whs10"> </p>
-<p class="whs9">isDone = pattern.MakeMesh(Mesh_1.GetMesh(),
+<p class="whs10">isDone = pattern.MakeMesh(Mesh_1.GetMesh(),
0, 0)</p>
-<p class="whs9">if (isDone != 1): print
+<p class="whs10">if (isDone != 1): print
'MakeMesh :', pattern.GetErrorCode() </p>
<script type="text/javascript" language="javascript1.2">
<html>\r
\r
<head>\r
-<title>Prism 3D Algorithm</title>\r
+<title>3D extrusion meshing algorithm</title>\r
<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
<!--\r
{\r
if (window.setRelStartPage)\r
{\r
- addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\nPrism 3D Algorithm");\r
+ addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\n3D extrusion meshing algorithm");\r
addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
\r
writeIntopicBar(4);\r
//-->\r
</script>\r
-<h1>Prism 3D Algorithm</h1>\r
+<h1>3D extrusion meshing algorithm</h1>\r
\r
-<p>Prism 3D algorithm can be used for meshing prisms, i.e. <span style="font-weight: bold;"><B>3D \r
- Shapes</B></span> defined by<span style="margin-left: 24px;\r
- margin-top: 0pt;\r
- margin-bottom: 0pt;"> two opposing \r
- faces having the same number of vertices and edges and meshed using the \r
+<p>3D extrusion algorithm can be used for meshing prisms, i.e.\r
+<span style="font-weight: bold;"><B>3D Shapes</B></span> defined by\r
+ two opposing faces having the same number of vertices and edges and meshed using the \r
<a href="projection_algorithms.htm">2D Projection</a> algorithm. These \r
- two faces should be connected by quadrangle "side" faces.</span></p>\r
+ two faces should be connected by quadrangle "side" faces.</p>\r
\r
<p><span style="margin-left: 24px;\r
margin-top: 0pt;\r
margin-bottom: 0pt;">The opposing faces can be meshed with \r
either quadrangles or triangles, while the side faces should be meshed \r
- with quadranglees only. </span></p>\r
+ with quadrangles only. </span></p>\r
\r
<p class="whs1"><img src="image157.gif" width="324px" height="337px" border="0" class="img_whs2"></p>\r
\r
<p class="whs1"> </p>\r
\r
-<p class="whs3">As you can see, the <span style="font-weight: bold;"><B>Prism3D</B></span> \r
+<p class="whs3">As you can see, the <span style="font-weight: bold;"><B>3D extrusion</B></span> \r
algorithm permits to build and to have in the same 3D mesh such elements \r
as hexahedrons, prisms and polyhedrons.</p>\r
\r
--- /dev/null
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Segments around Vertex Algorithm</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { margin-left:40px; }\r
+img_whs2 { border:none; width:270px; height:179px; float:none; border-style:none; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+ if (innerWidth != origWidth || innerHeight != origHeight)\r
+ location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+ origWidth = innerWidth;\r
+ origHeight = innerHeight;\r
+ onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+ if (window.setRelStartPage)\r
+ {\r
+ addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\nSegments around Vertex Algorithm");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+ }\r
+\r
+\r
+ if (window.setRelStartPage)\r
+ {\r
+ setRelStartPage("index.htm");\r
+\r
+ autoSync(1);\r
+ sendSyncInfo();\r
+ sendAveInfoOut();\r
+ }\r
+\r
+}\r
+else\r
+ if (window.gbIE4)\r
+ document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Segments around Vertex</h1>\r
+\r
+<p><span style="font-weight: bold;"><B>Segments around Vertex</B></span> algorithm \r
+ is considered to be a 0D \r
+ meshing algorithm, but, of course, it doesn't mesh nodes. It allows to \r
+ define the local size of the elements in the neighborhood of a certain \r
+ node. If we choose an object of higher dimension, it applies to all its \r
+ tops, i.e. corners of a box. The \r
+ 0D algorithm combines with the algorithms of higher dimensions, but it \r
+ is not necessarily required for their successful implementation. </p>\r
+\r
+<p>This algorithm allows only one hypothesis. </p>\r
+\r
+<p class="whs1"><img src="pics/lengthnearvertex.png" x-maintain-ratio="TRUE" width="270px" height="179px" border="0" class="img_whs2"></p>\r
+\r
+<p> </p>\r
+\r
+<p> </p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+ writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
aspect_ratio_3d.htm
borders_at_multi-connection.htm
borders_at_multiconnection_2d.htm
+building_compounds.htm
clipping.htm
constructing_meshes.htm
convert_to_from_quadratic_mesh.htm
length.htm
merge_elements.htm
mesh.htm
+mesh_through_point.htm
modifying_meshes.htm
namespacesmesh.html
netgen_2d_and_3d_hypotheses.htm
pattern_mapping.htm
presentation.htm
+prism_3d_algorithm.htm
+projection_algorithms.htm
quality_controls.htm
+radial_prism.htm
revolution.htm
+segments_around_vertex_algorithm.htm
selection_filter_library.htm
smesh.py_introduction.htm
transforming_meshes.htm
texture_horiz_ltbluebubbles.jpg
index.glo
default.css
-pics\add_node.png
+pics\curvi_simple_after.png
+pics\image89.gif
+pics\image100.gif
+pics\image78.gif
+pics\image23.gif
+pics\b-mesh_infos.png
pics\remove_nodes2.png
-pics\merging_nodes2.png
-pics\moving_nodes2.png
+pics\moving_nodes1.png
pics\smoothing2.png
-pics\b-mberofsegments.png
-pics\b-flection1d.png
-pics\a-cuttingofquadrangles.png
+pics\a-maxelarea.png
+pics\patternmapping1.png
+image94.jpg
+image106.gif
+image91.gif
+image80.gif
+pics\distributionwithtabledensity.png
+pics\moving_nodes2.png
+image7.jpg
+pics\patternmapping2.png
+pics\extrusionalongaline1.png
pics\addquadrangle.png
-pics\intersectgroups.png
-pics\editgroup.png
image95.jpg
pics\sewing1.png
image92.gif
image51.jpg
image70.gif
-pics\netgen2d.png
-pics\circle_simple_after.png
-pics\curvi_simple_after.png
-pics\image138.gif
-pics\create_group.png
-pics\edit_mesh_change_value_hyp.png
+pics\meshtopass.png
+pics\image157.gif
+pics\extrusion1.png
+pics\curvi_angles_after.png
+pics\straight_before.png
+pics\image102.gif
+pics\length2d.png
pics\free_borders1.png
-pics\add_triangle.png
-pics\b-art_end_length.png
pics\a-creategroup.png
-pics\a-clipping2.png
-pics\a-transparency.png
-pics\diagonalinversion.png
-pics\translation1.png
+pics\a-startendlength.png
+pics\a-patterntype.png
+pics\extrusionalongaline2.png
+pics\orientaation1.png
+pics\unionoftwotriangles.png
image96.jpg
pics\sewing2.png
image119.gif
image82.gif
image71.gif
image30.jpg
-pics\extrusion1.png
-pics\distributionwithanalyticdensity.png
-pics\image139.gif
-pics\rotation1.png
-pics\a-createpolyhedralvolume.png
-pics\a-patterntype.png
-pics\orientaation1.png
-pics\translation2.png
-pics\cutgroups.png
+pics\lengthnearvertex.png
+pics\straight_after.png
+pics\cut_groups1.png
+pics\uniting_a_set_of_triangles1.png
+pics\b-erage_length.png
+pics\removeelements.png
image97.jpg
pics\sewing3.png
image86.jpg
image94.gif
image83.gif
image31.jpg
-pics\circle_angles_after.png
-pics\circle_simple_before.png
-pics\curvi_angles_after.png
-pics\graduatedaxes1.png
-pics\image107.gif
-pics\automaticlength.png
+pics\aqt.png
+pics\distributionwithanalyticdensity.png
+pics\meshexportmesh.png
pics\image27.gif
-pics\add_polyhedron.png
-pics\add_edge.png
-pics\rotation2.png
-pics\b-ithmetic1d.png
+pics\cut_groups2.png
+pics\edit_mesh_change_value_hyp.png
+pics\add_node.png
+pics\uniting_a_set_of_triangles2.png
+pics\max_el_area.png
image10.jpg
-pics\a-maxelarea.png
+pics\a-filteronedges.png
+pics\revolution1.png
pics\addhexahedron.png
-pics\addtetrahedron.png
-image5.jpg
+pics\addtriangle.png
+pics\editgroup.png
pics\sewing4.png
image95.gif
image76.jpg
image84.gif
image32.jpg
image40.gif
-pics\curvi_simple_before.png
-pics\image108.gif
-pics\aqt.png
-pics\distributionwithtabledensity.png
-pics\smoothing.png
+i_blue.jpg
+image160.gif
+pics\number_of_layers.png
+pics\netgen2d.png
+pics\mesh_for_extr_along_path.png
+pics\meshtrianglemergeelem1.png
+pics\image138.gif
+pics\cut_groups3.png
+pics\revolution2.png
+pics\renumberelements.png
+pics\intersectgroups.png
image88.jpg
image30.gif
image96.gif
image63.gif
image22.jpg
image41.gif
-pics\edge_wire_3d_before.png
-pics\image109.gif
-pics\meshimportmesh.png
-pics\deletegroups.png
-pics\editing_groups1.png
-pics\uniting_two_triangles1.png
-image7.jpg
-pics\a-averagelength.png
-pics\a-patterntype1.png
-pics\extrusionalongaline1.png
-pics\movenodes.png
-pics\rotation.png
+image161.gif
+pics\createmesh-inv.png
+pics\image139.gif
+pics\b-art_end_length.png
+pics\b-mberofsegments.png
+pics\b-flection1d.png
+pics\a-unionoftriangles.png
image56.jpg
image53.gif
image20.gif
image78.jpg
image64.gif
image23.jpg
-pics\edge_wire_after.png
-pics\edge_wire_before.png
+pics\buildcompound.png
+pics\projection_3d.png
image151.gif
-pics\cut_groups1.png
-pics\editing_groups2.png
-pics\uniting_two_triangles2.png
-pics\a-unionoftriangles.png
-pics\a-arithmetic1d.png
-pics\extrusionalongaline2.png
+pics\selectionfilterlibrary.png
+pics\intersect_groups1.png
+pics\create_group.png
+pics\add_triangle.png
+pics\add_edge.png
+pics\rotation1.png
+pics\merging_nodes1.png
+pics\translation1.png
+pics\cutgroups.png
image79.jpg
image98.gif
image32.gif
+pics\projection_2d.png
+pics\advanced_mesh_infos.png
+pics\image108.gif
pics\image91.gif
image152.gif
-pics\cut_groups2.png
+pics\automaticlength.png
+pics\intersect_groups2.png
image130.gif
-pics\max_el_area.png
+pics\rotation2.png
+pics\merging_nodes2.png
+pics\a-cuttingofquadrangles.png
+pics\a-transparency.png
pics\a-viewgeneral.png
-pics\revolution1.png
-pics\addtriangle.png
+pics\smoothing.png
+pics\translation2.png
image99.gif
image55.gif
image88.gif
image36.jpg
image33.gif
image25.jpg
-i_blue.jpg
+pics\projection_1d.png
+pics\view_rotation_point.png
image153.gif
+pics\image109.gif
image15.jpg
image142.gif
-pics\cut_groups3.png
+pics\intersect_groups3.png
image131.gif
-pics\add_quadrangle.png
-pics\uniting_a_set_of_triangles1.png
-pics\a-deflection1d.png
-pics\revolution2.png
-pics\unionoftwotriangles.png
+pics\edit_mesh1.png
+pics\b-ithmetic1d.png
+pics\mergenodes.png
+pics\rotation.png
pics\addnode.png
image120.gif
image56.gif
image34.gif
pics\convert.png
image154.gif
+pics\edge_wire_3d_after.png
+pics\graduatedaxes1.png
+pics\length-crit.png
image143.gif
+pics\editing_groups1.png
image132.gif
-pics\edit_mesh1.png
-pics\remove_elements1.png
-pics\uniting_a_set_of_triangles2.png
-pics\mergenodes.png
-pics\symmetry1.png
+pics\a-maxelvolume.png
+pics\a-averagelength.png
+pics\movenodes.png
+pics\removenodes.png
+pics\addtetrahedron.png
+pics\uniongroups.png
image121.gif
image79.gif
image38.jpg
image35.gif
image27.jpg
image24.gif
+note1.gif
+pics\distribution_of_layers.png
image155.gif
-pics\mesh_for_extr_along_path.png
-pics\createmesh-inv2.png
+pics\edge_wire_after.png
+pics\edge_wire_before.png
image144.gif
-pics\intersect_groups1.png
+pics\deletegroups.png
+pics\editing_groups2.png
image133.gif
-pics\add_polygone.png
-pics\remove_elements2.png
-pics\a-maxelvolume.png
-pics\symmetry2.png
+pics\add_polyhedron.png
+pics\addedge.png
+pics\creategroup.png
image122.gif
image58.gif
image36.gif
image25.gif
-note1.gif
image156.gif
-pics\edge_wire_3d_after.png
-pics\createmesh-inv3.png
+pics\circle_simple_after.png
image145.gif
-pics\intersect_groups2.png
image134.gif
-pics\b-mesh_infos.png
-pics\symmetry3.png
-pics\addedge.png
+pics\edit_mesh_remove_hyp.png
+pics\a-patterntype1.png
image123.gif
image101.gif
image37.gif
-pics\straight_after.png
+image157.gif
pics\image96.gif
image146.gif
-pics\intersect_groups3.png
+pics\meshimportmesh.png
image135.gif
-pics\b-erage_length.png
-pics\a-standmeshinfo.png
+pics\uniting_two_triangles1.png
pics\a-nbsegments1.png
-pics\patternmapping1.png
+pics\a-arithmetic1d.png
+pics\symmetry1.png
image90.jpg
image124.gif
image49.gif
+pics\exemple.gif
image38.gif
-pics\image100.gif
+pics\set_rotation_point_dialog1.png
pics\image97.gif
-pics\length-crit.png
image147.gif
+pics\union_groups1.png
image136.gif
+pics\free_edges.png
+pics\uniting_two_triangles2.png
pics\a-nbsegments2.png
-pics\a-startendlength.png
-pics\patternmapping2.png
-pics\removeelements.png
-pics\removenodes.png
-pics\uniongroups.png
+pics\symmetry2.png
image125.gif
image103.gif
-pics\exemple.gif
image39.gif
image28.gif
-pics\advanced_mesh_infos.png
+image159.gif
+pics\set_rotation_point_dialog2.png
+pics\circle_angles_after.png
+pics\createmesh-inv2.png
pics\image98.gif
+pics\mergeelems.png
image148.gif
-pics\meshexportmesh.png
pics\image21.gif
-pics\union_groups1.png
+pics\union_groups2.png
image137.gif
-pics\free_edges.png
-pics\creategroup.png
+pics\add_quadrangle.png
+pics\remove_elements1.png
+pics\a-createpolyhedralvolume.png
+pics\a-clipping2.png
+pics\a-deflection1d.png
+pics\diagonalinversion.png
+pics\symmetry3.png
+pics\renumbernodes.png
image92.jpg
image126.gif
image18.gif
image70.jpg
-pics\straight_before.png
-pics\createmesh-inv.png
-pics\image102.gif
+pics\circle_simple_before.png
+pics\edge_wire_3d_before.png
+pics\curvi_simple_before.png
+pics\createmesh-inv3.png
pics\image99.gif
pics\image77.gif
-pics\meshtrianglemergeelem1.png
-pics\mergeelems.png
-pics\union_groups2.png
-pics\length2d.png
-pics\renumbernodes.png
+pics\union_groups3.png
+pics\add_polygone.png
+pics\remove_elements2.png
+pics\remove_nodes1.png
+pics\smoothing1.png
+pics\a-standmeshinfo.png
+pics\addpolygon.png
+image5.jpg
image127.gif
image93.jpg
image105.gif
image19.gif
image71.jpg
-pics\image89.gif
-pics\image78.gif
-pics\image23.gif
-pics\selectionfilterlibrary.png
-pics\union_groups3.png
-pics\edit_mesh_remove_hyp.png
-pics\remove_nodes1.png
-pics\merging_nodes1.png
-pics\moving_nodes1.png
-pics\smoothing1.png
-pics\a-filteronedges.png
-pics\renumberelements.png
-pics\addpolygon.png
-image94.jpg
-image106.gif
-image91.gif
-image80.gif
index.ppf
ehlpdhtm.js
default_ns.css
whgdata\whlstt7.htm
whgdata\whlstt8.htm
whgdata\whlstt9.htm
+whgdata\whlstt10.htm
whgdata\whlsti0.htm
whgdata\whlstfl0.htm
whgdata\whlstfl1.htm
whgdata\whlstfl23.htm
whgdata\whlstfl24.htm
whgdata\whlstfl25.htm
+whgdata\whlstfl26.htm
whgdata\whlstf0.htm
whgdata\whlstf1.htm
whgdata\whlstf2.htm
aTE("Aspect ratio 3D","aspect_ratio_3d.htm");
aTE("Borders at multi-connection","borders_at_multi-connection.htm");
aTE("Borders at multiconnection 2D","borders_at_multiconnection_2d.htm");
+aTE("Building Compounds","building_compounds.htm");
aTE("Clipping","clipping.htm");
aTE("Constructing Meshes","constructing_meshes.htm");
aTE("Convert to/from Quadratic Mesh","convert_to_from_quadratic_mesh.htm");
aTE("Length","length.htm");
aTE("Merge Elements","merge_elements.htm");
aTE("mesh","mesh.htm");
+aTE("Mesh through point","mesh_through_point.htm");
aTE("Modifying Meshes","modifying_meshes.htm");
aTE("SALOME - SMESH - v.version: Package smesh","namespacesmesh.html");
aTE("Netgen 2D and 3D hypotheses","netgen_2d_and_3d_hypotheses.htm");
aTE("Quality Controls","quality_controls.htm");
aTE("Radial Prism","radial_prism.htm");
aTE("Revolution","revolution.htm");
+aTE("Segments around Vertex Algorithm","segments_around_vertex_algorithm.htm");
aTE("Selection filter library","selection_filter_library.htm");
aTE("smesh.py_introduction","smesh.py_introduction.htm");
aTE("Transforming Meshes","transforming_meshes.htm");
</script>
<script language="javascript">
<!--
-aWE("_grp",72);
-aWE("0",14,19,5,6,25,8,12,57,61,63,68,43,72,73,75);
-aWE("000001",68);
-aWE("001",73);
-aWE("0d",14);
-aWE("1",17,1,18,19,20,2,21,23,6,7,26,8,27,28,29,30,11,12,57,31,32,35,36,61,64,68,39,40,70,62,43,44,72,45,47,73,49,50,51,76,54);
-aWE("10",6,8,12,57,31,61,72,73,75);
-aWE("100",6,8,57,68,72,73);
-aWE("109",73);
-aWE("110",61);
-aWE("113",73);
-aWE("12",61,73);
-aWE("13",61);
-aWE("130",61);
-aWE("15",61,68,73);
-aWE("150",8,61,73);
-aWE("17",61);
-aWE("180",61);
-aWE("1d",13,14,15,16,19,23,6,8,11,12,60,61,63,37,67,68,69,70,72);
-aWE("1e",61,68);
-aWE("2",17,1,18,20,2,21,23,6,7,26,8,27,28,29,30,11,12,31,32,36,61,64,68,39,40,70,62,43,44,45,47,73,49,50,51,76,54);
-aWE("20",6,8,57,61,68,72,73,75);
-aWE("200",6,8,61,72);
-aWE("21",61,73);
-aWE("23",61,73);
-aWE("24",73);
-aWE("240",61);
-aWE("245",61);
-aWE("246",61);
-aWE("25",73);
-aWE("255",61);
-aWE("2d",13,14,15,16,18,20,4,23,6,8,11,12,57,33,32,60,36,63,64,66,67,68,69,70,43,72,73,54);
-aWE("3",14,18,20,21,23,6,7,26,8,27,28,11,12,57,31,61,63,64,68,39,40,70,62,43,44,72,45,73,49,50,75,54);
-aWE("30",8,61,63,73);
-aWE("300",6);
-aWE("3128",61);
-aWE("321",61);
-aWE("3265",61);
-aWE("3402",61);
-aWE("35",57,68);
-aWE("3658",61);
-aWE("38",61,68,73);
-aWE("39",61);
-aWE("3d",13,14,15,16,0,17,1,20,2,21,23,6,25,26,8,9,27,28,29,11,12,60,63,34,66,67,68,69,39,40,70,43,72,45,49,50,76,53);
-aWE("3e",68);
-aWE("3rd",14);
-aWE("3x3",61);
-aWE("4",14,18,20,23,6,26,8,28,12,31,61,64,68,62,43,44,47,73,54);
-aWE("40",57,61,72);
-aWE("405",61);
-aWE("406",61);
-aWE("45",12,61,73);
-aWE("47",61);
-aWE("492",61);
-aWE("493",61);
-aWE("5",5,6,8,61,68,73);
-aWE("50",8,61,73);
-aWE("502",61);
-aWE("503",61);
-aWE("58",73);
-aWE("5th",14);
-aWE("6",2,6,8,57,61,73);
-aWE("60",57,61,72);
-aWE("66632",61);
-aWE("69",73);
-aWE("7",6,8,57,61,68);
-aWE("70",8,61,73);
-aWE("71",73);
-aWE("72",73);
-aWE("73",61);
-aWE("8",57,61,68,73);
-aWE("80",61,72);
-aWE("800",6);
-aWE("814",61);
-aWE("850",61);
-aWE("859",61);
-aWE("89",73);
-aWE("9",61,73);
-aWE("90",73);
-aWE("900",6,75);
-aWE("91",73);
-aWE("92",73);
-aWE("95",68);
-aWE("9999",25);
-aWE("a_mesh",61);
-aWE("a10",61);
-aWE("a45",61);
-aWE("aa",61);
-aWE("abl",17,1,53);
-aWE("abord",68);
-aWE("aborder",68);
-aWE("abov",61,45);
-aWE("absent",51);
-aWE("absolute",74);
-aWE("abut",19);
-aWE("acces",0,71,53);
-aWE("accord",16,18,19,20,2,32,36,64,44,45,47,76,54);
-aWE("account",13,64);
-aWE("acomp",73);
-aWE("actual",63,37);
-aWE("ad",17,1,21,7,25,26,57,61,49,51);
-aWE("add",17,1,21,23,25,26,8,30,12,57,61,68,71,72,49);
-aWE("addedg",61);
-aWE("addfac",61);
-aWE("addition",26,60,61);
-aWE("additional",13,14,23,8,37,64,42,71,45);
-aWE("addnod",61);
-aWE("addobject",57);
-aWE("addpolygonalfac",61);
-aWE("addpolyhedralvolum",61);
-aWE("addtostudy",6,8,57,61,68,72,73,75);
-aWE("addtostudyinfath",6,8,57,61);
-aWE("addvolum",61);
-aWE("adjacent",28,36,63,37,39,43,49);
-aWE("adjust",45);
-aWE("adjustabl",37);
-aWE("advanc",0,52);
-aWE("afilt",57,68);
-aWE("afiltermgr",68);
-aWE("ageomgroup",57);
-aWE("agroup",57,68);
-aWE("agroup1",57);
-aWE("agroup2",57);
-aWE("agroup3",57);
-aWE("agroup4",57);
-aWE("agroup5",57);
-aWE("agroupelemid",57);
-aWE("agroupf",68);
-aWE("agroupmain",57);
-aWE("agroupn",68);
-aWE("agroupr",57);
-aWE("agrouptool",57);
-aWE("ai",19);
-aWE("al",61);
-aWE("algeady",67);
-aWE("algo",8,61,68,73);
-aWE("algo_local",6,8,73);
-aWE("algo1d",6,8,57,61,72,73,75);
-aWE("algo2d",6,8,61,72,73,75);
-aWE("algo3d",6,8,72,75);
-aWE("algorithm",13,14,15,16,0,18,23,6,24,8,12,33,60,63,34,64,66,67,69,38,43);
-aWE("allow",13,0,1,19,21,24,7,25,26,31,33,59,35,60,63,37,64,67,41,43,45,46,48,49,51,53);
-aWE("along",11,12,61,64,45,53);
-aWE("already",67);
-aWE("alternativ",23);
+aWE("_grp",75);
+aWE("0",15,20,6,7,26,9,13,58,63,65,70,44,75,76,78);
+aWE("000001",70);
+aWE("001",76);
+aWE("0d",15,73);
+aWE("1",18,1,19,20,21,2,22,24,7,8,27,9,28,29,30,31,12,13,58,32,33,36,62,37,63,66,70,40,41,72,64,44,45,75,46,48,76,50,51,52,79,55);
+aWE("10",7,9,13,58,32,63,75,76,78);
+aWE("100",7,9,58,63,70,75,76);
+aWE("109",76);
+aWE("110",63);
+aWE("113",76);
+aWE("12",63,76);
+aWE("13",63);
+aWE("130",63);
+aWE("15",63,70,76);
+aWE("150",9,63,76);
+aWE("17",63);
+aWE("180",63);
+aWE("1d",14,15,16,17,20,24,7,9,12,13,61,63,65,38,69,70,71,72,75);
+aWE("1e",63,70);
+aWE("2",18,1,19,21,2,22,24,7,8,27,9,28,29,30,31,12,13,32,33,62,37,63,66,70,40,41,72,64,44,45,46,48,76,50,51,52,79,55);
+aWE("20",7,9,58,63,70,75,76,78);
+aWE("200",7,9,63,75);
+aWE("21",63,76);
+aWE("23",63,76);
+aWE("24",76);
+aWE("240",63);
+aWE("245",63);
+aWE("246",63);
+aWE("25",76);
+aWE("255",63);
+aWE("2d",14,15,16,17,19,21,4,24,7,9,12,13,58,34,33,61,37,65,66,68,69,70,71,72,44,75,76,55);
+aWE("3",15,19,21,22,24,7,8,27,9,28,29,12,13,58,32,62,63,65,66,70,40,41,72,64,44,45,75,46,76,50,51,78,55);
+aWE("30",9,63,65,76);
+aWE("300",7);
+aWE("3128",63);
+aWE("321",63);
+aWE("3265",63);
+aWE("3402",63);
+aWE("35",58,70);
+aWE("3658",63);
+aWE("38",63,70,76);
+aWE("39",63);
+aWE("3d",14,15,16,17,0,18,1,21,2,22,24,7,26,27,9,10,28,29,30,12,13,61,65,35,68,69,70,71,40,41,72,44,75,46,50,51,79,54);
+aWE("3e",70);
+aWE("3rd",15);
+aWE("3x3",63);
+aWE("4",15,19,21,24,7,27,9,29,13,32,62,63,66,70,64,44,45,48,76,55);
+aWE("40",58,63,75);
+aWE("405",63);
+aWE("406",63);
+aWE("45",13,63,76);
+aWE("47",63);
+aWE("492",63);
+aWE("493",63);
+aWE("5",6,7,9,63,70,76);
+aWE("50",9,63,76);
+aWE("502",63);
+aWE("503",63);
+aWE("58",76);
+aWE("5th",15);
+aWE("6",2,7,9,58,63,76);
+aWE("60",58,63,75);
+aWE("66632",63);
+aWE("69",76);
+aWE("7",7,9,58,63,70);
+aWE("70",9,63,76);
+aWE("71",76);
+aWE("72",76);
+aWE("73",63);
+aWE("8",58,63,70,76);
+aWE("80",63,75);
+aWE("800",7);
+aWE("814",63);
+aWE("850",63);
+aWE("859",63);
+aWE("89",76);
+aWE("9",63,76);
+aWE("90",76);
+aWE("900",7,78);
+aWE("91",76);
+aWE("92",76);
+aWE("95",70);
+aWE("9999",26);
+aWE("a_mesh",63);
+aWE("a10",63);
+aWE("a45",63);
+aWE("aa",63);
+aWE("abl",18,1,54);
+aWE("abord",70);
+aWE("aborder",70);
+aWE("abov",63,46);
+aWE("absent",52);
+aWE("absolute",77);
+aWE("abut",20);
+aWE("acces",0,74,54);
+aWE("accord",17,19,20,21,2,33,37,66,45,46,48,79,55);
+aWE("account",14,66);
+aWE("acomp",76);
+aWE("actual",65,38);
+aWE("ad",18,1,22,8,26,27,58,63,50,52);
+aWE("add",18,1,22,24,26,27,9,31,13,58,63,70,74,75,50);
+aWE("addedg",63);
+aWE("addfac",63);
+aWE("addition",27,61,63);
+aWE("additional",14,15,24,9,38,66,43,74,46);
+aWE("addnod",63);
+aWE("addobject",58);
+aWE("addpolygonalfac",63);
+aWE("addpolyhedralvolum",63);
+aWE("addtostudy",7,9,58,63,70,75,76,78);
+aWE("addtostudyinfath",7,9,58,63);
+aWE("addvolum",63);
+aWE("adjacent",29,37,65,38,40,44,50);
+aWE("adjust",46);
+aWE("adjustabl",38);
+aWE("advanc",0,53);
+aWE("afilt",58,70);
+aWE("afiltermgr",70);
+aWE("ageomgroup",58);
+aWE("agroup",58,70);
+aWE("agroup1",58);
+aWE("agroup2",58);
+aWE("agroup3",58);
+aWE("agroup4",58);
+aWE("agroup5",58);
+aWE("agroupelemid",58);
+aWE("agroupf",70);
+aWE("agroupmain",58);
+aWE("agroupn",70);
+aWE("agroupr",58);
+aWE("agrouptool",58);
+aWE("ai",20);
+aWE("al",63);
+aWE("algeady",69);
+aWE("algo",9,63,70,76);
+aWE("algo_local",7,9,76);
+aWE("algo1d",7,9,58,63,75,76,78);
+aWE("algo2d",7,9,63,75,76,78);
+aWE("algo3d",7,9,75,78);
+aWE("algorithm",14,15,16,17,0,19,24,7,25,9,13,34,61,65,35,66,68,69,71,39,73,44);
+aWE("allow",14,16,0,1,20,5,22,25,8,26,27,32,34,60,36,61,62,65,38,66,69,42,73,44,46,47,49,50,52,54);
+aWE("along",12,13,63,66,46,54);
+aWE("already",69);
+aWE("alternativ",24);
aWE("alternative",0,1);
-aWE("alway",45);
-aWE("amesh",6);
+aWE("alway",46);
+aWE("amesh",7);
aWE("amount",3);
-aWE("analytic",19);
-aWE("angl",16,5,26,12,60,36,61,68,70,41,44,73,49,54);
-aWE("angle270",73);
-aWE("angle45",61);
-aWE("angularity",12);
-aWE("anid",57,68);
-aWE("anoth",15,37,67);
-aWE("any",14,1,23,25,28,12,57,64,69,45);
-aWE("ap",15,17,1,18,20,2,21,5,23,7,25,26,8,9,27,28,30,11,12,32,59,60,36,61,64,67,38,39,40,70,43,44,45,46,47,49,50,51,76,54);
-aWE("api",72);
-aWE("apparent",23);
-aWE("appear",0,17,1,21,23,24,7,26,27,28,30,11,12,35,64,67,39,40,70,41,46,48,49,50,51);
-aWE("append",61);
-aWE("appli",18,19,20,2,23,24,33,32,36,34,37,69,38,71,44,45,47,76,54);
-aWE("applicabl",20,71);
-aWE("application",16,64);
-aWE("apply",13,0,23,24,25);
-aWE("applytomeshfac",61);
-aWE("appropriat",23);
-aWE("approximate",19);
-aWE("ar_margin",68);
-aWE("arc",8,73);
-aWE("arcsin",54);
-aWE("area",13,16,18,8,57,33,60,34,68,45,47,53);
-aWE("area_margin",68);
-aWE("arithmetic",13,19,6,8,60);
-aWE("arithmetic1d",6,8,73);
-aWE("around",5,12,70,53);
-aWE("array_of_nodes_group",73);
-aWE("asmeshgroup1",57);
-aWE("asmeshgroup2",57);
-aWE("aspect",16,20,2,60,68,45);
-aWE("assemb",72);
-aWE("assign",19,23,25,8,38,54);
-aWE("associat",17,29,39);
-aWE("attribut",25);
-aWE("auto",5);
-aWE("automatic",13,19,23,60,64);
-aWE("automatical",0,19,21,23,26,28,49);
-aWE("availabl",43,53);
-aWE("averag",13,19,8,33,60,64,54);
-aWE("ax",53);
-aWE("axi",11,61,70,41,46,73,53,54);
-aWE("axisstruct",61,73);
-aWE("axisxyz",61,73);
+aWE("analytic",20);
+aWE("angl",17,6,27,13,61,37,63,70,72,42,45,76,50,55);
+aWE("angle270",76);
+aWE("angle45",63);
+aWE("angularity",13);
+aWE("anid",58,70);
+aWE("anoth",16,38,69);
+aWE("any",15,16,1,24,26,29,13,58,62,63,66,71,46);
+aWE("ap",16,18,1,19,21,2,22,6,24,8,26,27,9,10,28,29,31,12,13,33,60,61,62,37,63,66,69,39,40,41,72,44,45,46,47,48,50,51,52,79,55);
+aWE("api",75);
+aWE("apparent",24);
+aWE("appear",0,18,1,5,22,24,25,8,27,28,29,31,12,13,36,62,66,69,40,41,72,42,47,49,50,51,52);
+aWE("append",63);
+aWE("appli",19,20,21,2,24,25,34,33,37,35,38,71,39,73,74,45,46,48,79,55);
+aWE("applicabl",21,74);
+aWE("application",17,66);
+aWE("apply",14,0,24,25,26);
+aWE("applytomeshfac",63);
+aWE("appropriat",24);
+aWE("approximate",20);
+aWE("ar_margin",70);
+aWE("arc",9,76);
+aWE("arcsin",55);
+aWE("area",14,17,19,9,58,34,61,35,70,46,48,54);
+aWE("area_margin",70);
+aWE("arithmetic",14,20,7,9,61);
+aWE("arithmetic1d",7,9,76);
+aWE("around",6,13,72,73,54);
+aWE("array_of_nodes_group",76);
+aWE("asmeshgroup1",58);
+aWE("asmeshgroup2",58);
+aWE("aspect",17,21,2,61,70,46);
+aWE("assemb",75);
+aWE("assign",16,20,24,26,9,39,55);
+aWE("associat",18,30,40);
+aWE("attribut",26);
+aWE("auto",6);
+aWE("automatic",14,20,24,61,62,66);
+aWE("automatical",0,20,22,24,27,29,50);
+aWE("automaticlength",63);
+aWE("availabl",44,54);
+aWE("averag",14,20,9,34,61,66,55);
+aWE("ax",54);
+aWE("axi",12,63,72,42,47,76,54,55);
+aWE("axisstruct",63,76);
+aWE("axisxyz",63,76);
aWE("background",0);
-aWE("bar",16);
-aWE("bas",13,18,8,12,60,54);
-aWE("basi",14,23,24);
-aWE("basic",13,15,0);
-aWE("bb",61);
-aWE("be",67);
-aWE("becom",63,64);
-aWE("befor",71,73);
-aWE("begin",19,43);
-aWE("belong",3,4,25,55,56,67,43,51);
-aWE("below",61,63,72);
-aWE("berder",43);
-aWE("bet",20);
-aWE("binary",71);
-aWE("bisect",54);
-aWE("bisector",54);
-aWE("bit",71);
+aWE("bar",17);
+aWE("bas",14,19,9,13,61,55);
+aWE("basi",15,24,25);
+aWE("basic",14,16,0);
+aWE("bb",63);
+aWE("be",69);
+aWE("becom",5,65,66);
+aWE("befor",74,76);
+aWE("begin",20,44);
+aWE("belong",3,4,26,56,57,69,44,52);
+aWE("below",63,65,75);
+aWE("berder",44);
+aWE("bet",21);
+aWE("binary",74);
+aWE("bisect",55);
+aWE("bisector",55);
+aWE("bit",74);
aWE("black",0);
aWE("blu",3);
-aWE("bmp",0,53);
-aWE("bog",19);
-aWE("boolean",61,51);
-aWE("bord",43,73);
-aWE("border",16,3,4,55,56,60,68,43,73);
-aWE("both",0,12,69,45,51);
-aWE("bottom",61,42);
-aWE("bound",14,64,53);
-aWE("boundari",64);
-aWE("boundary",13,25,64,43,45);
-aWE("box",17,1,19,21,23,6,24,7,26,8,27,28,30,11,12,57,31,59,35,63,64,67,68,39,40,70,41,42,71,43,72,45,46,73,48,49,50,51,52,75,53);
-aWE("box_1",61);
-aWE("box_cyl",72);
-aWE("box1",68,73);
-aWE("box2",68,73);
-aWE("broken",1,37);
-aWE("brown",25);
-aWE("brows",0,17,1,22,23,24,25,9,30,65,39,40,71,52);
-aWE("build",8,11,33,61,63,37,64,66,70,72);
-aWE("built",20,24,12,64,45);
-aWE("button",17,1,18,20,2,21,5,23,24,7,25,26,9,27,28,30,11,12,31,32,36,64,67,38,39,40,70,41,71,43,44,45,46,47,48,49,50,51,52,76,53,54);
-aWE("cad",14);
-aWE("cal",64);
-aWE("calculat",16,20,2,33,47);
-aWE("calculation",13,18,32,36);
-aWE("careful",39);
-aWE("cas",17,23,6,8,28,12,64,52);
-aWE("caviti",15);
-aWE("cc",61);
-aWE("cel",25,63,39,50);
-aWE("cent",12,45,53);
-aWE("central",12);
-aWE("centroid",45);
-aWE("centroidal",45);
-aWE("centroidal_smooth",61);
-aWE("certain",25,64);
-aWE("chang",0,19,21,6,28,61,37,38,53);
-aWE("characteristic",16);
-aWE("characteriz",14);
-aWE("check",25,63,43,53);
-aWE("checkbox",17,63,71,48);
-aWE("choic",13,23,64);
-aWE("choos",17,1,18,20,2,21,22,7,25,26,9,27,28,10,29,11,12,31,32,35,36,64,39,40,70,41,42,71,43,44,46,47,48,49,50,76,53,54);
-aWE("chosen",20,26,33,34,49);
-aWE("circl",12,73);
-aWE("circlemesh",73);
-aWE("circular",61);
-aWE("clas",62);
-aWE("clear",62,71);
-aWE("click",0,17,1,18,20,2,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,32,36,64,65,67,38,39,40,70,42,71,43,44,45,47,49,50,51,52,76,53,54);
-aWE("clip",0,5);
-aWE("clos",14,20,9,12,61,43);
-aWE("co",61,43);
-aWE("coars",19,7,63);
-aWE("coincid",59);
-aWE("coincident",12,59,35);
-aWE("color",16,0,18,20,2,25,32,36,44,47,76,53,54);
-aWE("combin",10,32,65,71);
-aWE("common",27,71,50);
-aWE("comp",68);
-aWE("compar",19,43);
-aWE("complete",59);
-aWE("complex",1,12);
-aWE("component",60,42);
-aWE("compos",13,14,15,16,0,19,2,29,33,34,69,44);
-aWE("compound",68);
-aWE("comput",0,19,23,6,8,57,61,64,68,43,72,73,75);
-aWE("computation",23,24,8,61);
-aWE("con",72);
-aWE("concept",37);
-aWE("concern",69);
-aWE("condition",13,25);
-aWE("confirm",21,26,30,39,45,49,51);
-aWE("confirmation",25);
-aWE("conform",13,37,43,73);
-aWE("conformity",20);
-aWE("connect",19,26,66,45);
-aWE("connection",14,16,3,4,60,68);
-aWE("connectivity",64);
-aWE("consid",20,23);
-aWE("consider",14,20,2,43);
-aWE("consist",16,1,18,19,20,3,4,22,23,24,25,12,55,56,57,33,32,36,34,69,47);
-aWE("consol",52);
-aWE("constant",19);
-aWE("construct",15,19,22,23,6,24,38);
-aWE("construction",19,23,6,24);
-aWE("contain",14,15,21,23,24,25,26,12,31,33,64,45,49);
-aWE("content",9,53);
-aWE("continu",45);
-aWE("contour",14,43);
-aWE("contrast",49);
-aWE("control",16,0,18,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54);
-aWE("converg",45);
-aWE("conversion",19,7);
-aWE("convert",7);
-aWE("coordinat",14,17,28,64,53);
-aWE("copy",41,71,46,73,48);
-aWE("corn",1,54);
-aWE("corner",26,12,45,54);
-aWE("correspond",14,16,31,64,68,71,43,48);
-aWE("cos_bot",61);
-aWE("cos_top",61);
-aWE("cosal",61);
-aWE("cot",72);
-aWE("could",14,17,67);
-aWE("count",43);
-aWE("counterclockwis",64);
-aWE("cours",23);
-aWE("cover",12);
-aWE("creat",14,0,17,1,19,5,23,6,24,25,8,30,57,35,60,61,63,37,64,67,68,38,41,71,72,46,73,48,51,75,54);
-aWE("createemptygroup",57,68);
-aWE("createfiltermanag",68);
-aWE("creategroup",57,61,68,72);
-aWE("createpolyedr",73);
-aWE("createpolygon",73);
-aWE("creation",14,37,64,38,62,72,51);
-aWE("criteria",60,71);
-aWE("criterion",18,20,2,25,26,57,58,32,36,68,71,44,47,49,76,54);
-aWE("cros",0,5,54);
-aWE("cubic",15);
-aWE("current",21,23,26,63,67,38,71,43,49);
-aWE("curv",14,19,12,61);
-aWE("curvilinear",19,12);
-aWE("custom",63);
-aWE("cut",19,6,26,8,57,61,51);
-aWE("cutgroup",57);
-aWE("cyl",8,72);
-aWE("cylind",8,72);
-aWE("d",19);
-aWE("data",62);
-aWE("dd",61);
-aWE("dea",31);
-aWE("deal",14);
-aWE("def",6,61,62);
-aWE("default",0,23,12,57,63,65,71,74,53);
-aWE("defin",14,15,1,19,20,5,23,6,24,25,8,12,61,63,37,64,66,67,62,43,72,73,53);
-aWE("definit",14,16,19,21,22,25,26,60,38,39,49);
-aWE("definition",0,19,6,12,33,63,34);
-aWE("deflection",13,19,8,60);
-aWE("deflection1d",8);
-aWE("deform",53);
-aWE("degre",20,5);
-aWE("delet",9,56,61,39,71);
-aWE("deletediag",61);
-aWE("deletion",39,50);
-aWE("density",19);
-aWE("depend",13,14,23,33,34);
-aWE("describ",14,15,64);
-aWE("description",64);
-aWE("desirabl",35);
-aWE("desktop",42);
-aWE("destin",14,16,60,62);
-aWE("detail",13,15,0);
-aWE("detalization",63);
-aWE("detect",35);
-aWE("dh",61);
-aWE("di1",72);
-aWE("diagonal",26,27,61,47);
-aWE("dialog",17,1,19,21,23,24,7,26,27,28,30,11,12,31,59,35,64,67,39,40,70,41,43,45,46,48,49,50,51);
-aWE("diamet",20);
-aWE("dif",1,63);
-aWE("differ",19);
-aWE("differenc",12,43);
-aWE("different",13,17,25,12,67,38,71,43);
-aWE("digit",12);
-aWE("dimension",14,2,23,11,63,70,52);
-aWE("direct",14,6,43,45);
-aWE("direction",12,64,54);
-aWE("dirstruct",61,73);
-aWE("discretiz",11,70);
-aWE("discretization",14,15);
-aWE("displac",28);
-aWE("display",16,0,1,18,20,2,3,21,23,24,25,26,28,10,29,55,32,36,65,44,45,47,49,52,76,53,54);
-aWE("distanc",19,5,64,53,54);
-aWE("distinguish",25);
-aWE("distortion",45);
-aWE("distribution",19,69);
-aWE("divid",19);
-aWE("do",17);
-aWE("docopy",73);
-aWE("documentation",62);
-aWE("domain",64);
-aWE("don",14,23,12,61,37,67,53);
+aWE("bmp",0,54);
+aWE("bog",20);
+aWE("boolean",63,52);
+aWE("bord",44,76);
+aWE("border",17,3,4,56,57,61,70,44,76);
+aWE("both",0,13,71,46,52);
+aWE("bottom",63,43);
+aWE("bound",15,66,54);
+aWE("boundari",66);
+aWE("boundary",14,26,66,44,46);
+aWE("box",18,1,20,5,22,24,7,25,8,27,9,28,29,31,12,13,58,32,60,36,62,63,65,66,69,70,40,41,72,42,43,73,74,44,75,46,47,76,49,50,51,52,53,78,54);
+aWE("box_1",63);
+aWE("box_cyl",75);
+aWE("box1",70,76);
+aWE("box2",70,76);
+aWE("break",63);
+aWE("broken",1,38);
+aWE("brown",26);
+aWE("brows",0,18,1,5,23,24,25,26,10,31,67,40,41,74,53);
+aWE("build",5,9,12,34,63,65,38,66,68,72,75);
+aWE("built",21,25,13,66,46);
+aWE("button",18,1,19,21,2,5,22,6,24,25,8,26,27,10,28,29,31,12,13,32,33,62,37,66,69,39,40,41,72,42,74,44,45,46,47,48,49,50,51,52,53,79,54,55);
+aWE("c1",16);
+aWE("cad",15);
+aWE("cal",66);
+aWE("calculat",17,21,2,34,48);
+aWE("calculation",14,19,33,37);
+aWE("careful",40);
+aWE("cas",18,5,24,7,9,29,13,62,66,53);
+aWE("caviti",16);
+aWE("cc",63);
+aWE("cel",26,65,40,51);
+aWE("cent",13,46,54);
+aWE("central",13);
+aWE("centroid",46);
+aWE("centroidal",46);
+aWE("centroidal_smooth",63);
+aWE("certain",26,62,66,73);
+aWE("chang",0,20,22,7,29,63,38,39,54);
+aWE("characteristic",17);
+aWE("characteriz",15);
+aWE("check",26,62,63,65,44,54);
+aWE("checkbox",18,65,74,49);
+aWE("choic",14,24,66);
+aWE("choos",18,1,19,21,2,5,22,23,8,26,27,10,28,29,11,30,12,13,32,33,36,62,37,66,40,41,72,42,43,73,74,44,45,47,48,49,50,51,79,54,55);
+aWE("chosen",21,5,27,34,35,50);
+aWE("circl",13,76);
+aWE("circlemesh",76);
+aWE("circular",63);
+aWE("clas",64);
+aWE("clear",64,74);
+aWE("click",0,18,1,19,21,2,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,33,62,37,66,67,69,39,40,41,72,43,74,44,45,46,48,50,51,52,53,79,54,55);
+aWE("clip",0,6);
+aWE("clos",15,21,10,13,63,44);
+aWE("closest",62);
+aWE("co",63,44);
+aWE("coars",20,8,65);
+aWE("coincid",60);
+aWE("coincident",5,13,60,36);
+aWE("color",17,0,19,21,2,26,33,37,45,48,79,54,55);
+aWE("combin",11,33,67,73,74);
+aWE("combination",5);
+aWE("common",28,74,51);
+aWE("comp",70);
+aWE("compar",20,44);
+aWE("complete",60);
+aWE("complex",1,13);
+aWE("component",61,43);
+aWE("compos",14,15,16,17,0,20,2,30,34,35,71,45);
+aWE("composit",16);
+aWE("compound",5,70);
+aWE("compound_mesh",5);
+aWE("comput",0,20,24,7,9,58,63,66,70,44,75,76,78);
+aWE("computation",24,25,9,63);
+aWE("con",75);
+aWE("concatenat",5);
+aWE("concept",38);
+aWE("concern",71);
+aWE("condition",14,26);
+aWE("confirm",22,27,31,40,46,50,52);
+aWE("confirmation",26);
+aWE("conform",14,38,44,76);
+aWE("conformity",21);
+aWE("connect",20,27,68,46);
+aWE("connection",15,17,3,4,61,70);
+aWE("connectivity",66);
+aWE("consid",21,24);
+aWE("consider",15,21,2,73,44);
+aWE("consist",17,1,19,20,21,3,4,23,24,25,26,13,56,57,58,34,33,37,35,71,48);
+aWE("consol",53);
+aWE("constant",20);
+aWE("construct",16,20,23,24,7,25,39);
+aWE("construction",20,24,7,25);
+aWE("contain",15,16,22,24,25,26,27,13,32,34,66,46,50);
+aWE("content",10,54);
+aWE("continu",46);
+aWE("contour",15,44);
+aWE("contrast",50);
+aWE("control",17,0,19,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55);
+aWE("converg",46);
+aWE("conversion",20,8);
+aWE("convert",8);
+aWE("coordinat",15,18,29,62,63,66,54);
+aWE("copy",42,74,47,76,49);
+aWE("corn",1,55);
+aWE("corner",27,13,73,46,55);
+aWE("correspond",15,17,32,66,70,74,44,49);
+aWE("cos_bot",63);
+aWE("cos_top",63);
+aWE("cosal",63);
+aWE("cot",75);
+aWE("could",15,18,69);
+aWE("count",44);
+aWE("counterclockwis",66);
+aWE("cours",24,73);
+aWE("cover",13);
+aWE("creat",15,0,18,1,20,5,6,24,7,25,26,9,31,58,36,61,62,63,65,38,66,69,70,39,42,74,75,47,76,49,52,78,55);
+aWE("createemptygroup",58,70);
+aWE("createfiltermanag",70);
+aWE("creategroup",58,63,70,75);
+aWE("createpolyedr",76);
+aWE("createpolygon",76);
+aWE("creation",15,62,38,66,39,64,75,52);
+aWE("criteria",61,74);
+aWE("criterion",19,21,2,26,27,58,59,33,37,70,74,45,48,50,79,55);
+aWE("cros",0,6,55);
+aWE("ctrl",5);
+aWE("cubic",16);
+aWE("current",22,24,27,65,69,39,74,44,50);
+aWE("curv",15,16,20,13,63);
+aWE("curvilinear",20,13);
+aWE("custom",65);
+aWE("cut",20,7,27,9,58,63,52);
+aWE("cutgroup",58);
+aWE("cyl",9,75);
+aWE("cylind",9,75);
+aWE("d",20);
+aWE("data",64);
+aWE("dd",63);
+aWE("dea",32);
+aWE("deal",15);
+aWE("def",7,63,64);
+aWE("default",0,24,13,58,65,67,74,77,54);
+aWE("defin",15,16,1,20,21,5,6,24,7,25,26,9,13,62,63,65,38,66,68,69,64,73,44,75,76,54);
+aWE("definit",15,17,20,22,23,26,27,61,39,40,50);
+aWE("definition",0,20,7,13,34,65,35);
+aWE("deflection",14,20,9,61);
+aWE("deflection1d",9);
+aWE("deform",54);
+aWE("degre",21,6);
+aWE("delet",10,57,63,40,74);
+aWE("deletediag",63);
+aWE("deletion",40,51);
+aWE("density",20);
+aWE("depend",14,15,24,34,35);
+aWE("describ",15,16,0,66);
+aWE("description",66);
+aWE("desirabl",36);
+aWE("desktop",43);
+aWE("destin",15,17,61,64);
+aWE("detail",14,16,0);
+aWE("detalization",65);
+aWE("detect",36);
+aWE("dh",63);
+aWE("di1",75);
+aWE("diagonal",27,28,63,48);
+aWE("dialog",18,1,20,5,22,24,25,8,27,28,29,31,12,13,32,60,36,62,66,69,40,41,72,42,44,46,47,49,50,51,52);
+aWE("diamet",21);
+aWE("dif",1,65);
+aWE("differ",20);
+aWE("differenc",13,44);
+aWE("different",14,18,26,13,69,39,74,44);
+aWE("digit",13);
+aWE("dimension",15,2,24,12,65,72,73,53);
+aWE("direct",15,7,44,46);
+aWE("direction",13,66,55);
+aWE("dirstruct",63,76);
+aWE("discretisation",16);
+aWE("discretiz",12,72);
+aWE("discretization",15);
+aWE("displac",29);
+aWE("display",17,0,1,19,21,2,3,22,24,25,26,27,29,11,30,56,33,37,67,45,46,48,50,53,79,54,55);
+aWE("distanc",20,6,66,54,55);
+aWE("distinguish",26);
+aWE("distortion",46);
+aWE("distribution",20,71);
+aWE("divid",20);
+aWE("do",18);
+aWE("docopy",76);
+aWE("documentation",0,64);
+aWE("doesn",73);
+aWE("domain",66);
+aWE("don",15,24,13,63,38,69,54);
aWE("doubl",1);
-aWE("downward",53);
-aWE("dr",61);
-aWE("drag",53);
-aWE("drawn",53);
-aWE("dump",0,53);
-aWE("duplicat",12);
-aWE("dx",61);
-aWE("dy",61);
-aWE("e",20,23,24,26,12,63,64,66,69,43,49);
-aWE("e_arc",8);
-aWE("e_straight",8);
-aWE("e1",61);
-aWE("easi",22);
-aWE("easy",62);
-aWE("edg",13,14,15,16,0,17,1,19,20,3,4,22,23,6,25,26,8,27,28,10,12,55,56,57,58,33,32,60,61,63,37,64,66,67,68,71,43,45,73,49,50,75,54);
-aWE("edge_",61);
-aWE("edge_bezierrr",61);
-aWE("edge_bezierrr_mesh",61);
-aWE("edge_circl",61);
-aWE("edge_circle_mesh",61);
-aWE("edge_straight",61);
-aWE("edge_straight_mesh",61);
-aWE("edge1",73);
-aWE("edgeslist",73);
-aWE("edgex",6,8);
-aWE("edit",6,9,30,57,35,38);
-aWE("edition",62,72);
-aWE("ee_1",61);
-aWE("ee_2",61);
-aWE("ee_3",61);
-aWE("ee_4",61);
-aWE("ee_5",61);
-aWE("ee_6",61);
-aWE("ee_7",61);
-aWE("effect",49);
-aWE("eith",64,66,43);
-aWE("element",13,14,15,16,0,17,1,18,19,20,2,4,21,22,7,25,26,8,9,27,28,29,30,11,12,56,57,33,32,59,60,36,61,63,34,37,64,66,68,39,40,70,41,71,43,44,45,46,47,73,48,49,51,52,76,54);
-aWE("els",6,8,61,64);
-aWE("empty",61);
-aWE("enabl",71);
-aWE("encapsulat",24);
-aWE("encounter",64);
-aWE("end",13,19,8,60,37,71,43,48);
-aWE("enough",43);
-aWE("ent",25,27,28,31,50);
-aWE("entiti",14,15);
-aWE("entity",14,0,10,71);
-aWE("equal",19,33,64,71,43,45);
-aWE("equidistant",19);
-aWE("equilateral",20);
+aWE("downward",54);
+aWE("dr",63);
+aWE("drag",54);
+aWE("drawn",54);
+aWE("dump",0,54);
+aWE("duplicat",13);
+aWE("dx",63);
+aWE("dy",63);
+aWE("e",21,24,25,27,13,65,66,68,71,73,44,50);
+aWE("e_arc",9);
+aWE("e_straight",9);
+aWE("e1",63);
+aWE("easi",23);
+aWE("easy",64);
+aWE("edg",14,15,16,17,0,18,1,20,21,3,4,23,24,7,26,27,9,28,29,11,13,56,57,58,59,34,33,61,63,65,38,66,68,69,70,74,44,46,76,50,51,78,55);
+aWE("edge_",63);
+aWE("edge_bezierrr",63);
+aWE("edge_bezierrr_mesh",63);
+aWE("edge_circl",63);
+aWE("edge_circle_mesh",63);
+aWE("edge_straight",63);
+aWE("edge_straight_mesh",63);
+aWE("edge1",76);
+aWE("edgeslist",76);
+aWE("edgex",7,9);
+aWE("edit",7,10,31,58,36,39);
+aWE("edition",64,75);
+aWE("ee_1",63);
+aWE("ee_2",63);
+aWE("ee_3",63);
+aWE("ee_4",63);
+aWE("ee_5",63);
+aWE("ee_6",63);
+aWE("ee_7",63);
+aWE("effect",50);
+aWE("eith",5,62,66,68,44);
+aWE("element",14,15,16,17,0,18,1,19,20,21,2,4,5,22,23,8,26,27,9,10,28,29,30,31,12,13,57,58,34,33,60,61,37,63,65,35,38,66,68,70,40,41,72,42,73,74,44,45,46,47,48,76,49,50,52,53,79,55);
+aWE("els",7,9,63,66);
+aWE("empty",63);
+aWE("enabl",74);
+aWE("encapsulat",25);
+aWE("encounter",66);
+aWE("end",14,20,9,61,38,74,44,49);
+aWE("enough",44);
+aWE("ent",26,28,29,32,62,51);
+aWE("entiti",15,16);
+aWE("entity",15,0,11,74);
+aWE("equal",20,34,66,74,44,46);
+aWE("equidistant",20);
+aWE("equilateral",21);
aWE("eras",0);
-aWE("error",61);
-aWE("etc",16,2,26,49);
-aWE("even",23,33,63);
-aWE("eventual",64);
-aWE("every",54);
-aWE("everyth",23);
-aWE("ex21_lamp",72);
-aWE("examin",12);
-aWE("exampl",14,2,23,6,25,12,64,62,72,51);
-aWE("exce",19);
-aWE("exceed",45);
-aWE("except",43,53);
-aWE("exist",13,21,25,26,30,64,71,49);
-aWE("existenc",23);
-aWE("explod",61);
-aWE("exponent",19);
-aWE("export",0,6,31,60,53);
-aWE("exportation",31);
-aWE("exportm",6);
-aWE("extend",53,54);
-aWE("external",12);
-aWE("extreme",19);
-aWE("extremiti",5);
-aWE("extrud",11,12,61,70);
-aWE("extrusion",11,12,61,73);
-aWE("extrusionalongpath",61,73);
-aWE("extrusionsweepobject",61);
-aWE("exy",8);
-aWE("f",19,8);
-aWE("f1",61);
-aWE("f2",61);
-aWE("f3",61);
-aWE("f4",61);
-aWE("f5",61);
-aWE("fac",13,14,15,0,17,19,2,3,22,23,6,24,25,8,10,12,55,57,33,60,61,63,37,64,66,67,68,71,43,72,73,52,75,54);
-aWE("face_1",61);
-aWE("face_2",61);
-aWE("face1",8,73);
-aWE("face2",73);
-aWE("facelist",68);
-aWE("faceslist1",73);
-aWE("faceslist2",73);
-aWE("facesrotat",61);
-aWE("factor",19,26);
-aWE("factoryserv",62);
-aWE("fail",61);
-aWE("far",43);
-aWE("fashion",12);
-aWE("fast",45);
-aWE("featur",25);
-aWE("ff",61);
-aWE("ff_1",61);
-aWE("ff_2",61);
-aWE("ff_3",61);
-aWE("ff_4",61);
-aWE("ff_5",61);
-aWE("ff_6",61);
-aWE("ff_7",61);
-aWE("field",17,1,21,25,27,28,67,40,71,43,45,49,50);
-aWE("fifth",43);
-aWE("fil",6,31,64,71);
-aWE("fill",68,69,40,43);
-aWE("filt",21,25,26,71,49);
-aWE("filter",25,71);
-aWE("fin",19,63);
-aWE("find",31,64,43);
-aWE("findcoincidentnod",73);
-aWE("findorloadcomponent",62);
-aWE("finenes",19,63);
-aWE("first",1,19,23,6,12,57,61,37,64,67,43);
-aWE("firstnodeid1",73);
-aWE("firstnodeid2",73);
-aWE("firstnodeidonfreebord",73);
-aWE("firstnodeidonsid",73);
-aWE("fit",53);
-aWE("fiv",61);
-aWE("fix",14,6,8,45);
-aWE("flag",64);
-aWE("fold",23,24);
-aWE("follow",13,14,17,1,2,21,23,24,7,25,26,27,28,29,30,11,12,35,61,64,67,39,40,70,41,43,45,46,48,49,50,51,52);
-aWE("font",53);
-aWE("form",1,27,30,64,43);
-aWE("format",0,31,60,53);
-aWE("formula",19,20,2);
-aWE("four",14,20,54);
-aWE("fourth",61);
-aWE("fram",53);
-aWE("fre",14,16,55,56,60,68,43,45,73);
-aWE("ft_area",57,68);
-aWE("ft_aspectratio",68);
-aWE("ft_aspectratio3d",68);
-aWE("ft_equalto",57,68);
-aWE("ft_freeborder",68);
-aWE("ft_length",68);
-aWE("ft_length2d",68);
-aWE("ft_lessthan",57,68);
-aWE("ft_minimumangl",61,68);
-aWE("ft_morethan",57,68);
-aWE("ft_multiconnection",68);
-aWE("ft_multiconnection2d",68);
-aWE("ft_skew",68);
-aWE("ft_tap",68);
-aWE("ft_volume3d",68);
-aWE("ft_warp",68);
-aWE("full_netgen",8);
-aWE("function",14,62);
-aWE("functionaliti",53);
-aWE("functionality",23,7,31,59,35,43,53);
-aWE("fus",72);
-aWE("futur",19);
-aWE("g",24);
-aWE("gaus",53);
-aWE("generat",13,14,16,19,23,60,37,64);
-aWE("generation",6,11,64,70,72);
-aWE("geom",14,60);
-aWE("geometric",14,16,8);
-aWE("geometrical",13,14,15,19,23,24,25,33,60,34,64,67,38,41,45,46,48,52);
-aWE("geometry",24,7,25,57,61,67,72,45);
-aWE("geompy",6,8,57,61,68,72,73,75);
-aWE("get",0,5,23,8,12,57,64,52);
-aWE("getedgenearpoint",6,8);
-aWE("geterrorcod",61);
-aWE("getfilt",57,68);
-aWE("getfreeborder",68);
-aWE("getidsfromfilt",57,68);
-aWE("getlistofid",57);
-aWE("getmesh",6,61);
-aWE("getnam",62);
-aWE("getpattern",61);
-aWE("ghs3d",62);
-aWE("giv",71,52);
-aWE("given",19,33,61,43);
-aWE("global",8,53);
-aWE("glu",68);
-aWE("good",6,45);
-aWE("got",64);
-aWE("graduat",53);
+aWE("error",63);
+aWE("etc",17,2,27,50);
+aWE("even",16,24,34,65);
+aWE("eventual",66);
+aWE("every",55);
+aWE("everyth",24);
+aWE("ex21_lamp",75);
+aWE("examin",13);
+aWE("exampl",15,2,5,24,7,26,13,66,64,75,52);
+aWE("exce",20);
+aWE("exceed",46);
+aWE("except",44,54);
+aWE("exist",14,5,22,26,27,31,62,66,74,50);
+aWE("existenc",24);
+aWE("explod",63);
+aWE("exponent",20);
+aWE("export",0,7,32,61,54);
+aWE("exportation",32);
+aWE("exportm",7);
+aWE("extend",54,55);
+aWE("external",13);
+aWE("extreme",20);
+aWE("extremiti",6);
+aWE("extrud",12,13,63,72);
+aWE("extrusion",12,13,63,76);
+aWE("extrusionalongpath",63,76);
+aWE("extrusionsweepobject",63);
+aWE("exy",9);
+aWE("f",20,9);
+aWE("f1",63);
+aWE("f2",63);
+aWE("f3",63);
+aWE("f4",63);
+aWE("f5",63);
+aWE("fac",14,15,16,0,18,20,2,3,23,24,7,25,26,9,11,13,56,58,34,61,63,65,38,66,68,69,70,74,44,75,76,53,78,55);
+aWE("face_1",63);
+aWE("face_2",63);
+aWE("face1",9,76);
+aWE("face2",76);
+aWE("facelist",70);
+aWE("faceslist1",76);
+aWE("faceslist2",76);
+aWE("facesrotat",63);
+aWE("factor",20,27);
+aWE("factoryserv",64);
+aWE("fail",63);
+aWE("far",44);
+aWE("fashion",13);
+aWE("fast",46);
+aWE("featur",26);
+aWE("ff",63);
+aWE("ff_1",63);
+aWE("ff_2",63);
+aWE("ff_3",63);
+aWE("ff_4",63);
+aWE("ff_5",63);
+aWE("ff_6",63);
+aWE("ff_7",63);
+aWE("field",18,1,22,26,28,29,69,41,74,44,46,50,51);
+aWE("fifth",44);
+aWE("fil",7,32,66,74);
+aWE("fill",70,71,41,44);
+aWE("filt",22,26,27,74,50);
+aWE("filter",26,74);
+aWE("fin",20,65);
+aWE("find",32,63,66,44);
+aWE("findcoincidentnod",76);
+aWE("findnodeclosestto",63);
+aWE("findorloadcomponent",64);
+aWE("finenes",20,65);
+aWE("first",1,20,24,7,13,58,63,38,66,69,44);
+aWE("firstnodeid1",76);
+aWE("firstnodeid2",76);
+aWE("firstnodeidonfreebord",76);
+aWE("firstnodeidonsid",76);
+aWE("fit",54);
+aWE("fiv",63);
+aWE("fix",15,7,9,46);
+aWE("flag",66);
+aWE("fold",24,25);
+aWE("follow",14,15,16,18,1,2,5,22,24,25,8,26,27,28,29,30,31,12,13,36,62,63,66,69,40,41,72,42,44,46,47,49,50,51,52,53);
+aWE("font",54);
+aWE("form",1,28,31,66,44);
+aWE("format",0,32,61,54);
+aWE("formula",20,21,2);
+aWE("four",15,21,55);
+aWE("fourth",63);
+aWE("fram",54);
+aWE("fre",15,17,56,57,61,70,44,46,76);
+aWE("ft_area",58,70);
+aWE("ft_aspectratio",70);
+aWE("ft_aspectratio3d",70);
+aWE("ft_equalto",58,70);
+aWE("ft_freeborder",70);
+aWE("ft_length",70);
+aWE("ft_length2d",70);
+aWE("ft_lessthan",58,70);
+aWE("ft_minimumangl",63,70);
+aWE("ft_morethan",58,70);
+aWE("ft_multiconnection",70);
+aWE("ft_multiconnection2d",70);
+aWE("ft_skew",70);
+aWE("ft_tap",70);
+aWE("ft_volume3d",70);
+aWE("ft_warp",70);
+aWE("full_netgen",9);
+aWE("function",15,63,64);
+aWE("functionaliti",54);
+aWE("functionality",24,8,32,60,36,44,54);
+aWE("fus",75);
+aWE("futur",20);
+aWE("g",25);
+aWE("gaus",54);
+aWE("generat",14,15,17,20,24,61,38,66);
+aWE("generation",7,12,66,72,75);
+aWE("geom",15,61);
+aWE("geometric",15,17,9);
+aWE("geometrical",14,15,16,20,24,25,26,34,61,35,66,69,39,42,46,47,49,53);
+aWE("geometry",25,8,26,58,63,69,75,46);
+aWE("geompy",7,9,58,63,70,75,76,78);
+aWE("get",0,6,24,9,13,58,66,53);
+aWE("getedgenearpoint",7,9);
+aWE("geterrorcod",63);
+aWE("getfilt",58,70);
+aWE("getfreeborder",70);
+aWE("getidsfromfilt",58,70);
+aWE("getlistofid",58);
+aWE("getmesh",7,63);
+aWE("getnam",64);
+aWE("getnodexyz",63);
+aWE("getpattern",63);
+aWE("getsubmeshnodesid",63);
+aWE("ghs3d",64);
+aWE("giv",74,53);
+aWE("given",20,34,63,44);
+aWE("global",9,54);
+aWE("glu",70);
+aWE("good",7,46);
+aWE("got",66);
+aWE("graduat",54);
aWE("graphical",0);
-aWE("great",19,53);
-aWE("greatest",20,2);
-aWE("green",25,12);
-aWE("group",21,22,25,26,9,30,12,57,35,60,61,68,71,72,45,48,49,51,52);
-aWE("group_nam",72);
-aWE("group1",51);
-aWE("group12",51);
-aWE("group12a",51);
-aWE("group12b",51);
-aWE("group2",51);
-aWE("groupongeom",57,61);
-aWE("grouprotat",61);
-aWE("groupsmooth",61);
-aWE("groupsofnod",73);
-aWE("grouptri",61);
-aWE("growth",63);
-aWE("h",54);
-aWE("half",20,54);
-aWE("halv",5);
-aWE("hasangl",61);
-aWE("hasrefpoint",61);
-aWE("hav",20,33,37,64,66);
-aWE("hedron",61);
-aWE("height",72,54);
-aWE("helical",12);
-aWE("help",16);
-aWE("henc",64);
-aWE("her",64);
-aWE("hexa",8);
-aWE("hexahedral",15,6,8);
-aWE("hexahedralization",23);
-aWE("hexahedrical",8);
-aWE("hexahedron",14,15,17,2,8,61,34,66,75);
-aWE("hh",61);
-aWE("hid",0,53);
-aWE("high",14);
-aWE("highlight",3,4,21,25,26,55,56,49);
-aWE("hmax",20);
-aWE("hol",56,61);
-aWE("hold",64);
-aWE("hollow",69);
-aWE("homogeneou",63);
-aWE("how",15,12,63,38);
-aWE("hyp",24,61);
-aWE("hyp1",6);
-aWE("hyp2",6);
-aWE("hyp3",6);
-aWE("hyp4",6);
-aWE("hypothes",13,0,19,23,6,24,8,33,60,63,37,69,38);
-aWE("hypothesi",13,19,23,6,8,33,61,34,37,38,72);
-aWE("i",15,20,23,26,12,57,31,61,63,64,66,68,69,43,49);
-aWE("icon",30,39,42);
-aWE("id",0,19,21,25,26,27,28,29,11,12,57,61,70,43,45,49,50);
-aWE("id_circl",73);
-aWE("id_fac",8);
-aWE("id_face1",73);
-aWE("idbox",6,68);
-aWE("idea",12);
-aWE("idl",6);
-aWE("idsofelement",61);
-aWE("idsoffixednod",61);
-aWE("idsofside1element",73);
-aWE("idsofside2element",73);
-aWE("if",14,17,5,23,6,24,7,8,11,12,57,33,61,63,37,64,67,68,38,39,70,71,43,45,49,53);
-aWE("ii",61);
-aWE("imag",0,12,53);
-aWE("imp",14);
-aWE("import",6,8,57,31,60,61,68,72,73,75);
-aWE("importation",31);
-aWE("in",69);
-aWE("includ",14,52);
-aWE("increas",6,8);
-aWE("index",25,64);
-aWE("indic",64);
-aWE("indicat",67,54);
-aWE("info",0,52,75);
-aWE("information",14,0,6,7,30,69,52,75);
-aWE("initial",12,61,71,46,51);
-aWE("input",1,19);
-aWE("inscrib",20);
-aWE("insert",71,43);
-aWE("instead",6,37,64);
-aWE("int",62);
-aWE("intact",9);
-aWE("integ",25);
-aWE("intend",43);
-aWE("interest",14);
-aWE("interfac",6,72);
-aWE("intermediat",43);
-aWE("internal",64,69);
-aWE("intersect",64,51);
-aWE("intersectgroup",57);
-aWE("intersection",57,64,69,51);
-aWE("introduc",13,25,37);
-aWE("introduction",60,72);
-aWE("invers",14,27,61);
-aWE("inversediag",61);
-aWE("inversion",27,61);
-aWE("invisibl",74);
-aWE("isdon",61);
-aWE("iso",64);
-aWE("isolin",64);
-aWE("isometric",53);
-aWE("isplanarfac",8,73);
-aWE("item",17,1,21,22,7,26,27,28,30,11,12,31,35,64,40,70,41,43,45,46,48,49,50,51);
-aWE("iteration",12,45);
-aWE("iterativ",45);
-aWE("iv",61);
-aWE("j",15,57,68);
-aWE("join",44);
-aWE("jpeg",0,53);
-aWE("jpg",0,53);
-aWE("just",1,64,39);
-aWE("k",15,19,20);
-aWE("keep",12,45,46);
-aWE("key",64);
-aWE("keyboard",26);
-aWE("know",64);
-aWE("ko",61);
-aWE("l",54);
-aWE("label",53);
-aWE("laplacian",45);
-aWE("last",1,19,12,37,43);
-aWE("lastnodeid1",73);
-aWE("lastnodeid2",73);
-aWE("lastnodeidonfreebord",73);
-aWE("lastnodeidonsid",73);
-aWE("lay",11,64,70);
-aWE("layer",69);
-aWE("lcc",62);
-aWE("learn",52);
-aWE("least",64,45);
-aWE("leav",23,9);
-aWE("left",0,12,64,53);
-aWE("len",57,61,68);
-aWE("length",13,16,19,20,6,8,58,33,32,60,68,43,53,54);
-aWE("length_margin",68);
-aWE("lengthfromedg",8,72,73);
-aWE("les",71,43,45);
-aWE("level",13,17,63);
-aWE("library",25,71);
-aWE("lik",17,2,29,43);
-aWE("limit",64,43,45);
-aWE("limitation",67);
-aWE("lin",14,1,19,11,37,64,70,44);
-aWE("linear",12,63);
-aWE("link",43);
-aWE("list",0,17,21,25,26,9,12,67,71,49);
-aWE("lk",19);
-aWE("ll",53);
-aWE("load",64,71);
-aWE("loadfromfac",61);
-aWE("local",6,24,8,60,37);
-aWE("locallength",8,72);
-aWE("locat",64,43,53);
-aWE("location",19,28,31,45);
-aWE("lock",26,45,53);
-aWE("longest",20);
-aWE("look",29,12,64,71);
-aWE("low",14,19,63);
-aWE("ly",64);
-aWE("main",21,26,9,12,37,64,71,49,51);
-aWE("makearc",8,73);
-aWE("makebezi",61);
-aWE("makebox",6,57,68,72,73,75);
-aWE("makeboxdxdydz",6,8,61);
-aWE("makecirclethreepnt",61,73);
-aWE("makecompound",68,73);
-aWE("makecon",72);
-aWE("makecylind",72);
-aWE("makecylinderrh",8);
-aWE("makeedg",8,61);
-aWE("makefac",8,73);
-aWE("makefus",72);
-aWE("makegluefac",68);
-aWE("makegroupbyid",57);
-aWE("makemesh",61);
-aWE("makepolygon",61);
-aWE("makepolylin",61);
-aWE("makequadmesh2",61);
-aWE("makeshell",68);
-aWE("makesketch",8);
-aWE("maketranslation",68);
-aWE("makevector",8,73);
-aWE("makevectordxdydz",72);
-aWE("makevertex",6,8,61,72,73);
-aWE("makewir",8,73);
-aWE("manag",13,17);
-aWE("manual",25,63,64,53);
-aWE("map",15,33,61,64);
-aWE("mark",53);
-aWE("mas",12);
-aWE("math",61,73);
-aWE("max",13,8,33,60,63,34,45);
-aWE("maxaspectratio",61);
-aWE("maxelementarea",6,8,61,68,75);
-aWE("maxelementvolum",6,8,72,75);
-aWE("maximum",19,8,33,63,34,44,45,52);
-aWE("maxnbofiteration",61);
-aWE("mean",14,63);
-aWE("meaningful",14);
-aWE("measur",54);
-aWE("medium",7);
-aWE("meet",26,49);
-aWE("mefisto",15,8);
-aWE("menu",17,1,19,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,35,37,64,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52);
-aWE("merg",59,35,43,73);
-aWE("mergeequalelement",73);
-aWE("mergenod",73);
-aWE("mesh",13,14,15,16,0,17,1,18,19,20,2,3,4,21,5,22,23,6,24,7,25,26,8,9,27,28,29,30,11,12,55,56,57,31,33,32,59,35,60,36,61,63,34,37,64,65,66,67,68,69,38,39,40,70,41,42,62,71,43,44,72,45,46,47,73,48,49,50,51,52,75,76,53,54);
-aWE("mesh_1",23,61);
-aWE("mesh_2",61);
-aWE("mesh_borders_at_multi",68);
-aWE("mesh_free_border",68);
-aWE("mesh_length_1d",68);
-aWE("mesh_length_2d",68);
-aWE("mesh_nam",61);
-aWE("mesh1d",61);
-aWE("mesh1d_tool",61);
-aWE("meshbox",6,75);
-aWE("mesheditor",61);
-aWE("meshm",6);
-aWE("method",61,45);
-aWE("middl",1,12,37);
-aWE("min_angl",68);
-aWE("minimum",16,19,26,60,36,63,68,43,49);
-aWE("mirror",73);
-aWE("mod",0,19,65);
-aWE("model",14,60);
-aWE("modification",14,17,1,21,7,26,27,28,30,11,12,35,60,64,39,40,70,41,43,45,46,48,49,50);
-aWE("modify",21,26,30,61,49);
-aWE("modul",14,15,1,19,6,25,60,42,72,53);
-aWE("mous",0,25,53);
-aWE("mov",28,61);
-aWE("movenod",61);
-aWE("much",63);
-aWE("multi",16,3,4,60,68);
-aWE("multiconnection",68);
-aWE("must",23,12,64,71,43);
-aWE("myelemid",68);
-aWE("mypnt1",68);
-aWE("mypnt2",68);
-aWE("n",64,43);
-aWE("n1",61);
-aWE("n10",61);
-aWE("n11",61);
-aWE("n12",61);
-aWE("n2",61);
-aWE("n23_param",8);
-aWE("n3",61);
-aWE("n4",61);
-aWE("n5",61);
-aWE("n6",61);
-aWE("n7",61);
-aWE("n8",61);
-aWE("n9",61);
-aWE("na",61);
-aWE("nam",23,6,24,25,30,57,31,61,63,67,62,71,72,51,53);
-aWE("nb",57,61,63,68);
-aWE("nb_conn",68);
-aWE("nb_vert",61);
-aWE("nbedg",6,73,75);
-aWE("nbfac",6,75);
-aWE("nbhexa",75);
-aWE("nbnod",6,73,75);
-aWE("nbpolygon",75);
-aWE("nbpolyhedron",75);
-aWE("nbprism",75);
-aWE("nbpyramid",75);
-aWE("nbquadrangl",73,75);
-aWE("nbseg",61);
-aWE("nbtetra",75);
-aWE("nbtriangl",73,75);
-aWE("nbvolum",6,73,75);
-aWE("nc",61);
-aWE("nd",61);
-aWE("ndiagonal",61);
-aWE("ne",23);
-aWE("necessary",17,67);
-aWE("need",69);
-aWE("negativ",19);
-aWE("neighbor",27,50);
-aWE("netgen",15,6,8,63,62,72,75);
-aWE("netgen_2d3d",8);
-aWE("new",0,5,23,24,25,28,61,64,38,71,51);
-aWE("new_id",61);
-aWE("next",19,64);
-aWE("nid",61);
-aWE("nid1",61);
-aWE("nid2",61);
-aWE("nid3",61);
-aWE("nid4",61);
-aWE("no_nam",62);
-aWE("nod",14,0,17,1,18,19,20,21,22,6,7,25,28,29,11,12,33,35,60,61,63,64,65,68,39,40,70,71,43,44,45,47,73,52,75,54);
-aWE("nodal",64,45);
-aWE("node_id",61);
-aWE("nodeid1ofside1tomerg",73);
-aWE("nodeid1ofside2tomerg",73);
-aWE("nodeid2ofside1tomerg",73);
-aWE("nodeid2ofside2tomerg",73);
-aWE("nodestart",61);
-aWE("non",23);
-aWE("nonam",62);
-aWE("normal",46,54);
-aWE("normalisation",20);
-aWE("not",17,20,23,25,9,12);
-aWE("noth",25);
-aWE("notic",14);
-aWE("now",5,23);
-aWE("nsmooth",61);
-aWE("numb",13,14,15,1,19,6,25,8,11,33,60,63,64,66,69,70,43,45,73,52,75,53);
-aWE("number",0,1,29,12);
-aWE("numberofsegment",6,8,57,61,68,73,75);
-aWE("numeric",26);
-aWE("numerical",13);
-aWE("nunit",61);
-aWE("obey",43);
-aWE("obj",62);
-aWE("object",13,15,0,17,1,19,5,22,23,24,7,25,26,9,30,31,33,61,63,34,64,65,67,38,39,40,41,48,49,52,76,53);
-aWE("objet",25);
-aWE("obtain",17,68);
-aWE("offset",53);
-aWE("ok",17,1,21,5,7,26,9,27,28,30,11,12,31,61,39,40,70,43,45,49,50,51);
-aWE("on",14,1,19,23,6,24,26,8,9,27,11,12,55,56,59,61,37,64,68,69,38,39,70,71,43,45,46,48,49,51);
-aWE("onc",49);
-aWE("onto",37,64);
-aWE("oo",20);
-aWE("opaqu",74);
-aWE("open",68);
-aWE("operat",13);
-aWE("operation",15,17,18,19,20,2,3,4,21,24,25,26,9,27,28,30,11,12,55,56,31,58,33,32,59,35,60,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54);
-aWE("oppos",66);
-aWE("opposit",13,5,6,26,8,33,37,43,44);
-aWE("optimiz",63);
-aWE("option",14,0,19,46,48);
-aWE("optional",23,12,67);
-aWE("ord",14,21,63,64);
-aWE("ordinary",1,37);
-aWE("orientat",53);
-aWE("orientation",21,5,26,61,67,49);
-aWE("origin",53,54);
-aWE("other",49);
-aWE("otherwis",23,33);
-aWE("our",23);
-aWE("out",69,53);
-aWE("outlin",56);
-aWE("outsid",64);
-aWE("own",14);
-aWE("p5",6,8);
-aWE("packag",6,62,72);
-aWE("pag",15,25,30);
-aWE("pair",19);
-aWE("pan",53);
-aWE("paramet",14,19,2,71,43);
-aWE("parameter",13,0,5,8,12,63,41,43,53);
-aWE("parametric",14,64);
-aWE("parent",24);
-aWE("part",61,43,45,53);
-aWE("particularity",14);
-aWE("pas",6,57,61,68);
-aWE("path",12,61,71,73);
-aWE("pathmesh",61);
-aWE("pathshap",61);
-aWE("pattern",61,64);
-aWE("pattern_nam",64);
-aWE("pentagonal",61);
+aWE("great",20,54);
+aWE("greatest",21,2);
+aWE("green",26,13);
+aWE("group",5,22,23,26,27,10,31,13,58,36,61,63,70,74,75,46,49,50,52,53);
+aWE("group_nam",75);
+aWE("group1",5,52);
+aWE("group1_1",5);
+aWE("group1_2",5);
+aWE("group12",52);
+aWE("group12a",52);
+aWE("group12b",52);
+aWE("group2",52);
+aWE("groupongeom",58,63);
+aWE("grouprotat",63);
+aWE("groupsmooth",63);
+aWE("groupsofnod",76);
+aWE("grouptri",63);
+aWE("growth",65);
+aWE("gui",0);
+aWE("h",55);
+aWE("half",21,55);
+aWE("halv",6);
+aWE("hasangl",63);
+aWE("hasrefpoint",63);
+aWE("hav",21,34,38,66,68);
+aWE("hedron",63);
+aWE("height",75,55);
+aWE("helical",13);
+aWE("help",17);
+aWE("henc",66);
+aWE("her",66);
+aWE("hexa",9);
+aWE("hexahedral",16,7,9);
+aWE("hexahedralization",24);
+aWE("hexahedrical",9);
+aWE("hexahedron",15,16,18,2,9,63,35,68,78);
+aWE("hh",63);
+aWE("hid",0,54);
+aWE("high",15,73);
+aWE("highlight",3,4,22,26,27,56,57,50);
+aWE("hmax",21);
+aWE("hol",57,63);
+aWE("hold",5,66);
+aWE("hollow",71);
+aWE("homogeneou",65);
+aWE("how",16,13,65,39);
+aWE("hyp",25,63);
+aWE("hyp1",7);
+aWE("hyp2",7);
+aWE("hyp3",7);
+aWE("hyp4",7);
+aWE("hypothes",14,16,0,20,24,7,25,9,34,61,65,38,71,39);
+aWE("hypothesi",14,16,20,24,7,9,34,63,35,38,39,73,75);
+aWE("i",16,21,24,27,13,58,32,63,65,66,68,70,71,73,44,50);
+aWE("icon",31,40,43);
+aWE("id",0,20,22,26,27,28,29,30,12,13,58,63,72,44,46,50,51);
+aWE("id_circl",76);
+aWE("id_fac",9);
+aWE("id_face1",76);
+aWE("idbox",7,70);
+aWE("idea",13);
+aWE("identical",5);
+aWE("idl",7);
+aWE("idsofelement",63);
+aWE("idsoffixednod",63);
+aWE("idsofside1element",76);
+aWE("idsofside2element",76);
+aWE("if",15,16,18,6,24,7,25,8,9,12,13,58,34,63,65,38,66,69,70,39,40,72,73,74,44,46,50,54);
+aWE("ii",63);
+aWE("imag",0,13,54);
+aWE("imp",15);
+aWE("implementation",73);
+aWE("import",7,9,58,32,61,63,70,75,76,78);
+aWE("importation",32);
+aWE("in",71);
+aWE("includ",15,53);
+aWE("increas",7,9);
+aWE("index",26,66);
+aWE("indic",66);
+aWE("indicat",62,69,55);
+aWE("info",0,53,78);
+aWE("information",15,0,5,7,8,31,71,53,78);
+aWE("initial",13,63,74,47,52);
+aWE("input",1,20);
+aWE("inscrib",21);
+aWE("insert",74,44);
+aWE("insid",63);
+aWE("instead",7,38,66);
+aWE("int",64);
+aWE("intact",10);
+aWE("integ",26);
+aWE("intend",44);
+aWE("interest",15);
+aWE("interfac",7,75);
+aWE("intermediat",44);
+aWE("internal",66,71);
+aWE("intersect",66,52);
+aWE("intersectgroup",58);
+aWE("intersection",58,66,71,52);
+aWE("introduc",14,26,38);
+aWE("introduction",61,75);
+aWE("invers",15,28,63);
+aWE("inversediag",63);
+aWE("inversion",28,63);
+aWE("invisibl",77);
+aWE("isdon",63);
+aWE("iso",66);
+aWE("isolin",66);
+aWE("isometric",54);
+aWE("isplanarfac",9,76);
+aWE("item",18,1,22,23,8,27,28,29,31,12,13,32,36,62,66,41,72,42,44,46,47,49,50,51,52);
+aWE("iteration",13,46);
+aWE("iterativ",46);
+aWE("iv",63);
+aWE("j",16,58,70);
+aWE("join",45);
+aWE("jpeg",0,54);
+aWE("jpg",0,54);
+aWE("just",1,66,40);
+aWE("k",16,20,21);
+aWE("keep",13,46,47);
+aWE("key",66);
+aWE("keyboard",27);
+aWE("know",66);
+aWE("ko",63);
+aWE("l",55);
+aWE("label",54);
+aWE("laplacian",46);
+aWE("last",1,20,13,38,44);
+aWE("lastnodeid1",76);
+aWE("lastnodeid2",76);
+aWE("lastnodeidonfreebord",76);
+aWE("lastnodeidonsid",76);
+aWE("lat",62);
+aWE("lay",12,66,72);
+aWE("layer",71);
+aWE("lcc",64);
+aWE("learn",53);
+aWE("least",66,46);
+aWE("leav",24,10);
+aWE("left",0,13,66,54);
+aWE("len",58,63,70);
+aWE("length",14,17,20,21,7,9,59,34,33,61,70,44,54,55);
+aWE("length_margin",70);
+aWE("lengthfromedg",9,75,76);
+aWE("les",74,44,46);
+aWE("level",14,18,65);
+aWE("library",26,74);
+aWE("lik",18,2,30,44);
+aWE("limit",66,44,46);
+aWE("limitation",69);
+aWE("lin",15,1,20,12,38,66,72,45);
+aWE("linear",13,65);
+aWE("link",44);
+aWE("list",0,18,22,26,27,10,13,69,74,50);
+aWE("lk",20);
+aWE("ll",54);
+aWE("load",66,74);
+aWE("loadfromfac",63);
+aWE("local",7,25,9,61,38,73);
+aWE("locallength",9,75);
+aWE("locat",66,44,54);
+aWE("location",20,29,32,63,46);
+aWE("lock",27,46,54);
+aWE("longest",21);
+aWE("look",30,13,66,74);
+aWE("low",15,20,65);
+aWE("ly",66);
+aWE("main",16,22,27,10,13,38,66,74,50,52);
+aWE("makearc",9,76);
+aWE("makebezi",63);
+aWE("makebox",7,58,70,75,76,78);
+aWE("makeboxdxdydz",7,9,63);
+aWE("makecirclethreepnt",63,76);
+aWE("makecompound",70,76);
+aWE("makecon",75);
+aWE("makecylind",75);
+aWE("makecylinderrh",9);
+aWE("makeedg",9,63);
+aWE("makefac",9,76);
+aWE("makefus",75);
+aWE("makegluefac",70);
+aWE("makegroupbyid",58);
+aWE("makemesh",63);
+aWE("makepolygon",63);
+aWE("makepolylin",63);
+aWE("makequadmesh2",63);
+aWE("makeshell",70);
+aWE("makesketch",9);
+aWE("maketranslation",70);
+aWE("makevector",9,76);
+aWE("makevectordxdydz",75);
+aWE("makevertex",7,9,63,75,76);
+aWE("makewir",9,76);
+aWE("manag",14,18);
+aWE("manual",26,62,65,66,54);
+aWE("map",16,34,63,66);
+aWE("mark",54);
+aWE("mas",13);
+aWE("math",63,76);
+aWE("max",14,9,34,61,65,35,46);
+aWE("maxaspectratio",63);
+aWE("maxelementarea",7,9,63,70,78);
+aWE("maxelementvolum",7,9,75,78);
+aWE("maximum",20,9,34,65,35,45,46,53);
+aWE("maxnbofiteration",63);
+aWE("mean",15,65);
+aWE("meaningful",15);
+aWE("measur",55);
+aWE("medium",8);
+aWE("meet",27,50);
+aWE("mefisto",16,9);
+aWE("menu",18,1,20,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,36,62,38,66,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53);
+aWE("merg",5,60,36,44,76);
+aWE("mergeequalelement",76);
+aWE("mergenod",76);
+aWE("mesh",14,15,16,17,0,18,1,19,20,21,2,3,4,5,22,6,23,24,7,25,8,26,27,9,10,28,29,30,31,12,13,56,57,58,32,34,33,60,36,61,62,37,63,65,35,38,66,67,68,69,70,71,39,40,41,72,42,43,64,73,74,44,45,75,46,47,48,76,49,50,51,52,53,78,79,54,55);
+aWE("mesh_1",5,24,63);
+aWE("mesh_2",5,63);
+aWE("mesh_borders_at_multi",70);
+aWE("mesh_free_border",70);
+aWE("mesh_length_1d",70);
+aWE("mesh_length_2d",70);
+aWE("mesh_nam",63);
+aWE("mesh1d",63);
+aWE("mesh1d_tool",63);
+aWE("meshbox",7,78);
+aWE("mesheditor",63);
+aWE("meshm",7);
+aWE("meshtopassthroughapoint",63);
+aWE("method",5,62,63,46);
+aWE("middl",1,13,38);
+aWE("min_angl",70);
+aWE("minimum",17,20,27,61,37,65,70,44,50);
+aWE("mirror",76);
+aWE("mod",0,20,67);
+aWE("model",15,61);
+aWE("modification",15,18,1,22,8,27,28,29,31,12,13,36,61,62,66,40,41,72,42,44,46,47,49,50,51);
+aWE("modify",22,27,31,63,50);
+aWE("modul",15,16,0,1,20,7,26,61,43,75,54);
+aWE("mous",0,26,54);
+aWE("mov",29,62,63);
+aWE("movement",62);
+aWE("movenod",63);
+aWE("much",65);
+aWE("multi",17,3,4,61,70);
+aWE("multiconnection",70);
+aWE("must",24,13,66,74,44);
+aWE("myelemid",70);
+aWE("mypnt1",70);
+aWE("mypnt2",70);
+aWE("n",63,66,44);
+aWE("n1",63);
+aWE("n10",63);
+aWE("n11",63);
+aWE("n12",63);
+aWE("n2",63);
+aWE("n23_param",9);
+aWE("n3",63);
+aWE("n4",63);
+aWE("n5",63);
+aWE("n6",63);
+aWE("n7",63);
+aWE("n8",63);
+aWE("n9",63);
+aWE("na",63);
+aWE("nam",5,24,7,25,26,31,58,32,63,65,69,64,74,75,52,54);
+aWE("namesak",5);
+aWE("nb",58,63,65,70);
+aWE("nb_conn",70);
+aWE("nb_vert",63);
+aWE("nbedg",7,76,78);
+aWE("nbfac",7,78);
+aWE("nbhexa",78);
+aWE("nbnod",7,76,78);
+aWE("nbpolygon",78);
+aWE("nbpolyhedron",78);
+aWE("nbprism",78);
+aWE("nbpyramid",78);
+aWE("nbquadrangl",76,78);
+aWE("nbseg",63);
+aWE("nbtetra",78);
+aWE("nbtriangl",76,78);
+aWE("nbvolum",7,76,78);
+aWE("nc",63);
+aWE("nd",63);
+aWE("ndiagonal",63);
+aWE("ne",24);
+aWE("necessari",73);
+aWE("necessary",18,62,69);
+aWE("need",71);
+aWE("negativ",20);
+aWE("neighbor",28,51);
+aWE("neighborhood",73);
+aWE("netgen",16,7,9,65,64,75,78);
+aWE("netgen_2d3d",9);
+aWE("new",0,6,24,25,26,29,62,63,66,39,74,52);
+aWE("new_id",63);
+aWE("next",20,66);
+aWE("nid",63);
+aWE("nid1",63);
+aWE("nid2",63);
+aWE("nid3",63);
+aWE("nid4",63);
+aWE("no_nam",64);
+aWE("nod",15,0,18,1,19,20,21,5,22,23,7,8,26,29,30,12,13,34,36,61,62,63,65,66,67,70,40,41,72,73,74,44,45,46,48,76,53,78,55);
+aWE("nodal",66,46);
+aWE("node_id",63);
+aWE("node000",63);
+aWE("nodeid",63);
+aWE("nodeid1ofside1tomerg",76);
+aWE("nodeid1ofside2tomerg",76);
+aWE("nodeid2ofside1tomerg",76);
+aWE("nodeid2ofside2tomerg",76);
+aWE("nodestart",63);
+aWE("non",24,63);
+aWE("nonam",64);
+aWE("normal",47,55);
+aWE("normalisation",21);
+aWE("not",18,21,24,26,10,13);
+aWE("noth",26);
+aWE("notic",15);
+aWE("now",6,24);
+aWE("nsmooth",63);
+aWE("numb",14,15,16,1,20,7,26,9,12,34,61,65,66,68,71,72,44,46,76,53,78,54);
+aWE("number",0,1,30,13);
+aWE("numberofsegment",7,9,58,63,70,76,78);
+aWE("numeric",27);
+aWE("numerical",14);
+aWE("nunit",63);
+aWE("obey",44);
+aWE("obj",64);
+aWE("object",14,16,0,18,1,20,5,6,23,24,25,8,26,27,10,31,32,34,63,65,35,66,67,69,39,40,41,42,73,49,50,53,79,54);
+aWE("objet",26);
+aWE("obtain",18,70);
+aWE("offset",54);
+aWE("ok",18,1,22,6,8,27,10,28,29,31,12,13,32,62,63,40,41,72,44,46,50,51,52);
+aWE("on",15,16,1,20,24,7,25,27,9,10,28,12,13,56,57,60,62,63,38,66,70,71,39,40,72,73,74,44,46,47,49,50,52);
+aWE("onc",50);
+aWE("onto",38,66);
+aWE("oo",21);
+aWE("opaqu",77);
+aWE("open",70);
+aWE("operat",14);
+aWE("operation",16,18,19,20,21,2,3,4,5,22,25,26,27,10,28,29,31,12,13,56,57,32,59,34,33,60,36,61,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55);
+aWE("oppos",68);
+aWE("opposit",14,6,7,27,9,34,38,44,45);
+aWE("optimiz",65);
+aWE("option",15,0,20,47,49);
+aWE("optional",24,13,69);
+aWE("ord",15,22,65,66);
+aWE("ordinary",1,38);
+aWE("orientat",54);
+aWE("orientation",22,6,27,63,69,50);
+aWE("origin",54,55);
+aWE("other",50);
+aWE("otherwis",24,34);
+aWE("our",24);
+aWE("out",71,54);
+aWE("outlin",57);
+aWE("outsid",66);
+aWE("own",15);
+aWE("p5",7,9);
+aWE("packag",7,64,75);
+aWE("pag",16,26,31);
+aWE("pair",20);
+aWE("pan",54);
+aWE("paramet",15,20,2,74,44);
+aWE("parameter",14,0,6,9,13,65,42,44,54);
+aWE("parametric",15,66);
+aWE("parent",25);
+aWE("part",63,44,46,54);
+aWE("particularity",15);
+aWE("pas",7,58,62,63,70);
+aWE("path",13,63,74,76);
+aWE("pathmesh",63);
+aWE("pathshap",63);
+aWE("pattern",63,66);
+aWE("pattern_nam",66);
+aWE("pentagonal",63);
aWE("pentahedron",2);
-aWE("per",63);
-aWE("perform",60,61,40,43,46,51,53);
-aWE("perimet",20);
-aWE("permit",66,67);
-aWE("pi",61,73);
-aWE("pictur",3,25,12,55,56,59);
-aWE("piec",72);
-aWE("plac",7,43,53);
-aWE("plan",5,68,46,54);
-aWE("planar",61,54);
-aWE("platform",25,42);
-aWE("pleas",9,12);
-aWE("plot",19);
-aWE("plu",11,70);
-aWE("png",0,53);
-aWE("point",14,1,19,12,61,37,64,67,70,41,43,46,73,48,53,54);
-aWE("pointstruct",61,73);
-aWE("polygon",17,61,75);
-aWE("polygonal",61);
-aWE("polyhedral",17,61);
-aWE("polyhedron",17,61,66,75);
-aWE("polylin",12);
-aWE("pop",9,29);
-aWE("position",14,64,53);
-aWE("posses",63,37);
-aWE("possibility",71);
-aWE("possibl",13,2,25,63,64);
-aWE("post",53);
-aWE("powerful",71);
-aWE("precision",17);
-aWE("preferenc",13,33,60,65);
-aWE("prefix",71);
-aWE("preproces",25);
-aWE("pres",17,1,12,39,53);
-aWE("present",14,0,63,51);
-aWE("presentation",16,0,53);
-aWE("preserv",64);
-aWE("preset",13);
-aWE("preview",17,5,26,64,71);
-aWE("previou",19,12,49);
-aWE("previous",24,25,60,64);
-aWE("principl",12);
-aWE("print",6,8,57,61,68,73,75);
-aWE("printmeshinfo",6);
-aWE("prism",66,69,75);
-aWE("prism3d",66);
-aWE("prismatic",15);
-aWE("pro",53);
-aWE("problem",6,8);
-aWE("proce",23,9);
-aWE("procedur",45);
-aWE("proceed",12,38);
-aWE("proces",45);
-aWE("produc",14,7,11,70,45);
-aWE("product",54);
-aWE("program",23);
-aWE("progression",19);
-aWE("project",64);
-aWE("projection",15,64,66,67,69,54);
-aWE("prompt",19);
-aWE("propagat",6,8,37);
-aWE("propagation",13,6,8,37,73);
-aWE("properti",53);
-aWE("prov",63);
-aWE("provid",0,17,26,72);
-aWE("pseudo",27);
-aWE("pt1",72);
-aWE("pt2",72);
-aWE("pul",45);
-aWE("put",8);
-aWE("px",8,73);
-aWE("px1",73);
-aWE("py",8,73);
-aWE("py1",73);
-aWE("pyramid",75);
-aWE("pyramidal",15);
-aWE("python",6,62,72,52);
-aWE("pz",8,73);
-aWE("pz1",73);
-aWE("q1",61);
+aWE("per",65);
+aWE("perform",61,63,41,44,47,52,54);
+aWE("perimet",21);
+aWE("permit",68,69);
+aWE("pi",63,76);
+aWE("pictur",3,26,13,56,57,60);
+aWE("piec",75);
+aWE("plac",8,44,54);
+aWE("plan",6,70,47,55);
+aWE("planar",63,55);
+aWE("platform",26,43);
+aWE("pleas",10,13);
+aWE("plot",20);
+aWE("plu",12,72);
+aWE("png",0,54);
+aWE("point",15,1,20,13,62,63,38,66,69,72,42,44,47,76,49,54,55);
+aWE("pointstruct",63,76);
+aWE("polygon",18,63,78);
+aWE("polygonal",63);
+aWE("polyhedral",18,63);
+aWE("polyhedron",18,63,68,78);
+aWE("polylin",13);
+aWE("pop",10,30);
+aWE("position",15,66,54);
+aWE("posses",65,38);
+aWE("possibility",74);
+aWE("possibl",14,2,5,26,65,66);
+aWE("post",54);
+aWE("powerful",74);
+aWE("precision",18);
+aWE("preferenc",14,34,61,67);
+aWE("prefix",74);
+aWE("preproces",26);
+aWE("pres",18,1,13,40,54);
+aWE("present",15,0,65,52);
+aWE("presentation",17,0,54);
+aWE("preserv",66);
+aWE("preset",14);
+aWE("preview",18,6,27,62,66,74);
+aWE("previou",20,13,50);
+aWE("previous",25,26,61,66);
+aWE("principl",13);
+aWE("print",7,9,58,63,70,76,78);
+aWE("printmeshinfo",7);
+aWE("prism",68,71,78);
+aWE("prism3d",68);
+aWE("prismatic",16);
+aWE("pro",54);
+aWE("problem",7,9);
+aWE("proce",24,10);
+aWE("procedur",46);
+aWE("proceed",13,39);
+aWE("proces",5,46);
+aWE("produc",15,8,12,72,46);
+aWE("product",55);
+aWE("program",24);
+aWE("progression",20);
+aWE("project",66);
+aWE("projection",16,66,68,69,71,55);
+aWE("prompt",20);
+aWE("propagat",7,9,38);
+aWE("propagation",14,7,9,38,76);
+aWE("properti",54);
+aWE("prov",65);
+aWE("provid",16,0,18,27,75);
+aWE("pseudo",28);
+aWE("pt1",75);
+aWE("pt2",75);
+aWE("pul",46);
+aWE("put",9);
+aWE("px",9,76);
+aWE("px1",76);
+aWE("py",9,76);
+aWE("py1",76);
+aWE("pyramid",78);
+aWE("pyramidal",16);
+aWE("python",7,64,75,53);
+aWE("pz",9,76);
+aWE("pz1",76);
+aWE("q1",63);
aWE("qi",2);
-aWE("qk",20,2);
-aWE("quad",54);
-aWE("quad_1",61);
-aWE("quad_2",61);
-aWE("quad_3",61);
-aWE("quad_4",61);
-aWE("quad_5",61);
-aWE("quad_6",61);
-aWE("quad_7",61);
-aWE("quadra",6,57);
-aWE("quadrangl",13,14,15,17,18,20,2,6,26,8,27,11,12,57,33,32,60,36,61,63,66,69,70,44,73,75);
-aWE("quadrangle",66);
-aWE("quadrangular",15,6,8,33,37);
-aWE("quadratic",13,1,7,63,37);
-aWE("quadtotri",61);
-aWE("quality",16,0,18,19,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54);
-aWE("quantity",13);
-aWE("r1",61);
-aWE("radial",69);
-aWE("radio",21,25,26,41,43,46,49);
-aWE("radiu",20,61,63);
-aWE("radius",63);
-aWE("radius_1",72);
-aWE("radius_2",72);
-aWE("rang",19,25,57,61,63,68);
-aWE("rat",63);
-aWE("ratio",16,20,2,60,68,45,47,54);
-aWE("ready",23);
+aWE("qk",21,2);
+aWE("quad",55);
+aWE("quad_1",63);
+aWE("quad_2",63);
+aWE("quad_3",63);
+aWE("quad_4",63);
+aWE("quad_5",63);
+aWE("quad_6",63);
+aWE("quad_7",63);
+aWE("quadra",7,58);
+aWE("quadrangl",14,15,16,18,19,21,2,7,27,9,28,12,13,58,34,33,61,37,63,65,68,71,72,45,76,78);
+aWE("quadrangle",68);
+aWE("quadrangular",16,7,9,34,38);
+aWE("quadratic",14,1,8,65,38);
+aWE("quadtotri",63);
+aWE("quality",17,0,19,20,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55);
+aWE("quantity",14);
+aWE("r1",63);
+aWE("radial",71);
+aWE("radio",22,26,27,42,44,47,50);
+aWE("radiu",21,63,65);
+aWE("radius",65);
+aWE("radius_1",75);
+aWE("radius_2",75);
+aWE("rais",63);
+aWE("rang",20,26,58,63,65,70);
+aWE("rat",65);
+aWE("ratio",17,21,2,61,70,46,48,55);
+aWE("ready",24);
aWE("recent",0);
-aWE("red",56);
-aWE("redefin",0,53);
-aWE("reduc",45);
-aWE("reevaluat",45);
-aWE("refer",64);
-aWE("referenc",14,16,23,24);
-aWE("refin",13);
-aWE("reflect",64,44,76);
-aWE("refpoint",61);
+aWE("red",57);
+aWE("redefin",0,54);
+aWE("reduc",46);
+aWE("reevaluat",46);
+aWE("refer",66);
+aWE("referenc",15,17,24,25);
+aWE("refin",14);
+aWE("reflect",66,45,79);
+aWE("refpoint",63);
aWE("refresh",0);
-aWE("regular",20,6,8,63,62);
-aWE("relat",42);
-aWE("relation",14);
-aWE("relationship",14);
-aWE("remot",53);
-aWE("remov",21,6,25,26,9,30,12,57,61,68,39,71,49);
-aWE("removal",60);
-aWE("removeelement",61,68);
-aWE("removehypothesi",6);
-aWE("removenod",61);
-aWE("renumb",40);
-aWE("renumber",61,40);
-aWE("renumbernod",61);
-aWE("reorient",21,61);
-aWE("replac",43);
-aWE("represent",13,14,19,2,65,47,53);
-aWE("representation",14);
-aWE("requir",27,28,63,50);
-aWE("res",61);
-aWE("reset",53);
-aWE("resiz",53);
-aWE("respect",12);
+aWE("regular",21,7,9,65,64);
+aWE("relat",43);
+aWE("relation",15);
+aWE("relationship",15);
+aWE("remot",54);
+aWE("remov",22,7,26,27,10,31,13,58,63,70,40,74,50);
+aWE("removal",61);
+aWE("removeelement",63,70);
+aWE("removehypothesi",7);
+aWE("removenod",63);
+aWE("renam",5);
+aWE("renumb",41);
+aWE("renumber",63,41);
+aWE("renumbernod",63);
+aWE("reorient",22,63);
+aWE("replac",44);
+aWE("represent",14,15,20,2,67,48,54);
+aWE("representation",15);
+aWE("requir",28,29,65,73,51);
+aWE("res",63);
+aWE("reset",54);
+aWE("resiz",54);
+aWE("respect",13);
aWE("respectiv",1);
-aWE("rest",64,43);
-aWE("restor",53);
-aWE("restrict",14);
-aWE("result",13,17,12,57,68,45,51);
-aWE("ret",6,8);
-aWE("retriev",14);
-aWE("return",58,61);
-aWE("reveal",20);
-aWE("revers",1,64);
-aWE("revert",21);
-aWE("revolution",11,61,70);
-aWE("revolv",61,70);
-aWE("right",0,22,9,28,29,12,65);
-aWE("rotat",11,12,61,70,41,73,53);
-aWE("rotation",5,70,41,73,53);
-aWE("rotationsweepobject",61);
-aWE("rough",13);
-aWE("rr",61);
-aWE("rul",19,37,43);
-aWE("run",42);
-aWE("salom",25,8,57,60,61,68,42,62,73);
-aWE("sam",14,0,19,20,2,23,24,8,12,37,66,67,38,71,43,51);
-aWE("sampl",15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54);
-aWE("sav",71);
-aWE("scal",19,53);
-aWE("scalar",16);
-aWE("scen",53);
-aWE("script",15,17,18,19,20,2,3,4,21,23,6,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54);
-aWE("se",15,17,18,19,20,2,3,4,21,5,6,24,7,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,66,38,39,40,70,41,43,44,72,45,46,47,48,49,50,51,76,53,54);
-aWE("seam",64);
-aWE("search",31,71);
-aWE("second",17,61,63,43);
-aWE("secondnodeid1",73);
-aWE("secondnodeid2",73);
-aWE("secondnodeidonfreebord",73);
-aWE("section",0,5,23,64,72);
-aWE("seg",63);
-aWE("segment",13,19,6,8,57,33,60,61,63,68,72,73,75);
-aWE("select",13,0,17,1,19,21,22,23,6,24,7,25,26,9,27,28,30,11,12,31,35,61,63,37,64,65,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52,53);
-aWE("selectabl",59);
-aWE("selection",17,1,21,25,26,9,71,49);
-aWE("sens",14);
-aWE("separat",47);
-aWE("sequenc",43);
-aWE("set",14,15,17,19,21,5,23,25,8,28,12,33,60,61,63,34,64,65,69,71,43,45,74,49,53);
-aWE("setmaxelementarea",6);
-aWE("setnam",62,72);
-aWE("setting",23);
-aWE("seven",12,61);
-aWE("sew",12,43,73);
-aWE("sewbordertosid",73);
-aWE("sewconformfreeborder",73);
-aWE("sewfreeborder",73);
-aWE("sewsideelement",73);
-aWE("sg",57,61,68,73);
-aWE("shad",0,65,74);
-aWE("shall",21,27,28,35,64,70,41,46,48,49,50);
-aWE("shap",13,14,15,12,61,64,66,67,69,45);
-aWE("shape_mesh",61);
-aWE("shape1d",61);
-aWE("shapetyp",6,8,57,61,68,72,73);
-aWE("shel",69);
-aWE("shell",68,69);
-aWE("shift",17,1,26,39,45);
-aWE("shortest",54);
-aWE("should",19,7,25,11,12,64,66,69,70,41,71,43,45,51);
-aWE("show",19,5,12,71,53);
-aWE("shown",16,45);
-aWE("shrink",65);
-aWE("sid",6,8,36,63,66,43,44,73);
-aWE("simp",23,37);
-aWE("simpl",14,17,12,64);
-aWE("simplex",20,2);
-aWE("sin",61);
-aWE("sin_bot",61);
-aWE("sin_top",61);
-aWE("six",12,61);
-aWE("siz",0,63,72,45);
-aWE("sk",20,2);
-aWE("sketch",8);
-aWE("sketcher",8);
-aWE("sketcher1",8);
-aWE("sketcher2",8);
-aWE("skew",16,26,60,68,44,49);
-aWE("skew_margin",68);
-aWE("slid",74);
-aWE("small",53);
-aWE("smesh",6,8,57,61,68,62,43,72,73,75);
-aWE("smesh_mechanic",57,61,68,73);
-aWE("smesh_mechanic_tetra",68);
-aWE("smeshgroup1",57);
-aWE("smooth",61,45);
-aWE("smoothobject",61);
-aWE("smp",64);
-aWE("so",13,19,20,12,64,43,47);
-aWE("solid",8,60,67);
-aWE("somewhat",17);
-aWE("soon",6);
-aWE("sort",21,25,26,49);
-aWE("sourc",67,71);
-aWE("spac",14,64,69,41,48);
-aWE("specifi",19,3,64,39,43,45);
-aWE("specific",15,22,71);
-aWE("specify",17,1,26,11,12,64,39,70,41,71,45,46,48,51);
-aWE("spher",19,20,23);
-aWE("split",15,19,2,5,63,43);
-aWE("sqrt",61);
-aWE("standalon",25,57,71);
-aWE("standard",0,7,31,72,52);
-aWE("start",13,19,5,8,12,60,42,43,48);
-aWE("startendlength",8);
-aWE("static",62);
-aWE("step",11,70);
-aWE("stor",64,71);
-aWE("str",62);
-aWE("straight",1,8,12,61,37);
-aWE("stretch",53);
-aWE("strict",53);
-aWE("structur",23,24,61,62);
-aWE("study",8,57,71,72);
-aWE("stuf",53);
-aWE("styl",6);
-aWE("sub",6,8,12,31,35,64,41,43,46,48);
-aWE("submenu",17,10,39,40);
-aWE("submesh",13,21,22,6,24,25,26,11,12,38,70,45,48,49,52);
-aWE("subshapeall",6,8,57,61,68,73);
-aWE("subshapeallid",72);
-aWE("subshapeallsort",61);
-aWE("subshapelist",6,57);
-aWE("subshapenam",6);
-aWE("succed",8);
+aWE("rest",66,44);
+aWE("restor",54);
+aWE("restrict",15);
+aWE("result",14,18,5,13,58,62,70,46,52);
+aWE("ret",7,9);
+aWE("retriev",15);
+aWE("return",59,63);
+aWE("reveal",21);
+aWE("revers",1,66);
+aWE("revert",22);
+aWE("revolution",12,63,72);
+aWE("revolv",63,72);
+aWE("right",0,23,10,29,30,13,67);
+aWE("rotat",12,13,63,72,42,76,54);
+aWE("rotation",6,72,42,76,54);
+aWE("rotationsweepobject",63);
+aWE("rough",14);
+aWE("rr",63);
+aWE("rul",20,38,44);
+aWE("run",43);
+aWE("salom",26,9,58,61,63,70,43,64,76);
+aWE("sam",15,16,0,20,21,2,24,25,9,13,38,68,69,39,74,44,52);
+aWE("sampl",16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55);
+aWE("sav",74);
+aWE("scal",20,54);
+aWE("scalar",17);
+aWE("scen",54);
+aWE("script",16,18,19,20,21,2,3,4,22,24,7,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55);
+aWE("se",16,18,19,20,21,2,3,4,5,22,6,7,25,8,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,68,39,40,41,72,42,44,45,75,46,47,48,49,50,51,52,79,54,55);
+aWE("seam",66);
+aWE("search",32,62,74);
+aWE("second",18,63,65,44);
+aWE("secondnodeid1",76);
+aWE("secondnodeid2",76);
+aWE("secondnodeidonfreebord",76);
+aWE("section",0,6,24,66,75);
+aWE("seg",65);
+aWE("segment",14,16,20,7,9,58,34,61,63,65,70,73,75,76,78);
+aWE("select",14,0,18,1,20,5,22,23,24,7,25,8,26,27,10,28,29,31,12,13,32,36,62,63,65,38,66,67,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53,54);
+aWE("selectabl",60);
+aWE("selection",18,1,22,26,27,10,74,50);
+aWE("sens",15);
+aWE("separat",48);
+aWE("sequenc",44);
+aWE("set",15,16,18,20,22,6,24,26,9,29,13,34,61,63,65,35,66,67,71,74,44,46,77,50,54);
+aWE("setmaxelementarea",7);
+aWE("setnam",64,75);
+aWE("setting",24);
+aWE("seven",13,63);
+aWE("sew",13,44,76);
+aWE("sewbordertosid",76);
+aWE("sewconformfreeborder",76);
+aWE("sewfreeborder",76);
+aWE("sewsideelement",76);
+aWE("sg",58,63,70,76);
+aWE("shad",0,67,77);
+aWE("shall",22,28,29,36,62,66,72,42,47,49,50,51);
+aWE("shap",14,15,16,13,63,66,68,69,71,46);
+aWE("shape_mesh",63);
+aWE("shape1d",63);
+aWE("shapetyp",7,9,58,63,70,75,76);
+aWE("shel",71);
+aWE("shell",70,71);
+aWE("shift",18,1,27,40,46);
+aWE("shortest",55);
+aWE("should",20,8,26,12,13,66,68,71,72,42,74,44,46,52);
+aWE("show",20,6,13,74,54);
+aWE("shown",17,46);
+aWE("shrink",67);
+aWE("sid",16,7,9,37,65,68,44,45,76);
+aWE("simp",5,24,38);
+aWE("simpl",15,18,13,66);
+aWE("simplex",21,2);
+aWE("sin",63);
+aWE("sin_bot",63);
+aWE("sin_top",63);
+aWE("six",13,63);
+aWE("siz",0,65,73,75,46);
+aWE("sk",21,2);
+aWE("sketch",9);
+aWE("sketcher",9);
+aWE("sketcher1",9);
+aWE("sketcher2",9);
+aWE("skew",17,27,61,70,45,50);
+aWE("skew_margin",70);
+aWE("slid",77);
+aWE("small",54);
+aWE("smesh",7,9,58,63,70,64,44,75,76,78);
+aWE("smesh_mechanic",58,63,70,76);
+aWE("smesh_mechanic_tetra",70);
+aWE("smeshgroup1",58);
+aWE("smooth",63,46);
+aWE("smoothobject",63);
+aWE("smp",66);
+aWE("so",14,20,21,13,66,44,48);
+aWE("solid",9,61,69);
+aWE("somewhat",18);
+aWE("soon",7);
+aWE("sort",22,26,27,50);
+aWE("sourc",69,74);
+aWE("spac",15,66,71,42,49);
+aWE("specifi",20,3,66,40,44,46);
+aWE("specific",16,23,74);
+aWE("specify",18,1,27,12,13,66,40,72,42,74,46,47,49,52);
+aWE("spher",20,21,24);
+aWE("split",16,20,2,6,65,44);
+aWE("sqrt",63);
+aWE("standalon",26,58,74);
+aWE("standard",0,8,32,75,53);
+aWE("start",14,20,6,9,13,61,43,44,49);
+aWE("startendlength",9);
+aWE("static",64);
+aWE("step",12,72);
+aWE("stor",66,74);
+aWE("str",63,64);
+aWE("straight",1,9,13,63,38);
+aWE("stretch",54);
+aWE("strict",54);
+aWE("structur",24,25,63,64);
+aWE("study",9,58,74,75);
+aWE("stuf",54);
+aWE("styl",7);
+aWE("sub",7,9,13,32,36,66,42,44,47,49);
+aWE("submenu",18,11,40,41);
+aWE("submesh",14,22,23,7,25,26,27,12,13,39,72,46,49,50,53);
+aWE("subshapeall",7,9,58,63,70,76);
+aWE("subshapeallid",63,75);
+aWE("subshapeallsort",63);
+aWE("subshapelist",7,58);
+aWE("subshapenam",7);
+aWE("succed",9);
+aWE("successful",73);
aWE("sum",2);
-aWE("supplement",37);
-aWE("supplementary",26);
-aWE("surfac",14,20,2,11,12,64,70,43);
-aWE("surround",14,45);
-aWE("swept",11,70);
+aWE("supplement",38);
+aWE("supplementary",27);
+aWE("surfac",15,21,2,12,13,66,72,44);
+aWE("surround",15,46);
+aWE("swept",12,72);
aWE("switch",1);
-aWE("symmetrical",46,73);
-aWE("symmetry",46,73);
-aWE("syntax",71);
-aWE("t",14,19,2,23,37,64,65,53);
-aWE("t1",61);
-aWE("tabl",1,19);
-aWE("tak",20,49);
-aWE("taken",13,22,25,8,64);
-aWE("tap",16,25,60,68,47);
-aWE("taper_margin",68);
-aWE("target",67);
-aWE("techniqu",45);
-aWE("tetra",6,8,72,75);
-aWE("tetrahedral",15,8,63,72);
-aWE("tetrahedralization",23);
-aWE("tetrahedrical",8);
-aWE("tetrahedron",14,15,17,2,6,8,61,34,72,75);
-aWE("tetran",8);
-aWE("th",64,43);
-aWE("them",13,17,1,19,2,25,9,10,11,12,35,63,39,70,43,45,53);
-aWE("themesh",6);
-aWE("third",12);
-aWE("thos",26,49);
-aWE("thre",14,1,20,61,63,37,43,46);
-aWE("threshold",71);
-aWE("tick",53);
+aWE("symmetrical",47,76);
+aWE("symmetry",47,76);
+aWE("syntax",74);
+aWE("t",15,20,2,24,38,66,67,73,54);
+aWE("t1",63);
+aWE("tabl",1,20);
+aWE("tak",21,50);
+aWE("taken",14,23,26,9,66);
+aWE("tap",17,26,61,70,48);
+aWE("taper_margin",70);
+aWE("target",69);
+aWE("techniqu",46);
+aWE("test",63);
+aWE("tetra",7,9,75,78);
+aWE("tetrahedral",16,9,65,75);
+aWE("tetrahedralization",24);
+aWE("tetrahedrical",9);
+aWE("tetrahedron",15,16,18,2,7,9,63,35,75,78);
+aWE("tetran",9);
+aWE("th",66,44);
+aWE("them",14,18,1,20,2,26,10,11,12,13,36,65,40,72,44,46,54);
+aWE("themesh",7);
+aWE("third",13);
+aWE("thos",27,50);
+aWE("thre",15,1,21,63,65,38,44,47);
+aWE("threshold",74);
+aWE("tick",54);
aWE("tim",0);
-aWE("tmp",6);
-aWE("togeth",33);
-aWE("toggl",17,71,48);
-aWE("toleranc",35,70,71,73);
-aWE("tool",71,51);
-aWE("toolbar",20,2,21,23,24,7,26,27,28,30,11,12,32,64,39,40,70,42,44,45,47,49,50,52,76,53,54);
-aWE("top",61);
-aWE("topological",14,43);
-aWE("topology",14);
-aWE("toru",7);
-aWE("total",52);
-aWE("toward",45);
-aWE("transform",28,73);
-aWE("transformation",35,41,43,46,48);
-aWE("translat",73,48);
-aWE("translation",73,48);
-aWE("transparency",0,74);
-aWE("transparent",74);
-aWE("transtorm",7);
-aWE("tria",6,8,73);
-aWE("tria_mesh",8);
-aWE("triangl",14,15,17,1,18,20,6,8,27,11,33,32,59,36,61,63,66,68,69,70,44,72,47,73,49,50,75,53);
-aWE("triangular",15,33);
-aWE("triangulation",8);
-aWE("trihedron",53);
-aWE("tritoquad",61);
-aWE("truncat",72);
-aWE("try",23,63);
-aWE("tt",8,61);
-aWE("tui",15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54);
-aWE("tupl",62);
-aWE("two",14,17,5,25,26,8,27,12,57,36,61,63,64,66,67,68,69,43,47,73,48,50,51,52);
-aWE("typ",14,17,19,20,2,22,23,25,11,12,39,70,71,43,52);
-aWE("typical",45);
-aWE("u",14,43);
-aWE("unary",71);
-aWE("unassign",38);
-aWE("uncheck",53);
-aWE("uniform",45);
-aWE("union",57,49,50,51);
-aWE("uniongroup",57);
-aWE("unionid",72);
-aWE("unit",61,43,49,50,51);
-aWE("unles",37);
-aWE("unv",31);
-aWE("up",19,9,29);
-aWE("updat",0,6,42,45);
-aWE("updateobjbrows",57,61,68,73);
-aWE("upload",71);
-aWE("us",14,15,19,3,5,23,24,25,11,12,33,35,61,63,64,66,70,71,43,45,74,51,53);
-aWE("usag",16,6,61,72);
-aWE("useful",0,17,25,12,63);
-aWE("usual",43,45);
-aWE("v",14);
-aWE("valu",13,16,19,20,2,23,6,12,58,36,37,38,71,44,72);
-aWE("vari",20);
-aWE("variabl",62);
+aWE("tmp",7);
+aWE("togeth",34);
+aWE("toggl",18,74,49);
+aWE("toleranc",5,36,72,74,76);
+aWE("tool",74,52);
+aWE("toolbar",21,2,5,22,24,25,8,27,28,29,31,12,13,33,62,66,40,41,72,43,45,46,48,50,51,53,79,54,55);
+aWE("top",63,73);
+aWE("topological",15,44);
+aWE("topology",15);
+aWE("toru",8);
+aWE("total",53);
+aWE("toward",46);
+aWE("transform",29,76);
+aWE("transformation",36,42,44,47,49);
+aWE("translat",76,49);
+aWE("translation",76,49);
+aWE("transparency",0,77);
+aWE("transparent",77);
+aWE("transtorm",8);
+aWE("tria",7,9,76);
+aWE("tria_mesh",9);
+aWE("triangl",15,16,18,1,19,21,7,9,28,12,34,33,60,37,63,65,68,70,71,72,45,75,48,76,50,51,78,54);
+aWE("triangular",16,34);
+aWE("triangulation",9);
+aWE("trihedron",54);
+aWE("tritoquad",63);
+aWE("tru",63);
+aWE("truncat",75);
+aWE("try",24,65);
+aWE("tt",9,63);
+aWE("tui",16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55);
+aWE("tupl",64);
+aWE("two",15,18,6,26,27,9,28,13,58,37,63,65,66,68,69,70,71,44,48,76,49,51,52,53);
+aWE("typ",15,18,20,21,2,23,24,26,12,13,40,72,74,44,53);
+aWE("typical",46);
+aWE("u",15,44);
+aWE("unary",74);
+aWE("unassign",39);
+aWE("uncheck",54);
+aWE("uniform",46);
+aWE("union",58,50,51,52);
+aWE("uniongroup",58);
+aWE("unionid",75);
+aWE("unit",5,63,44,50,51,52);
+aWE("unles",38);
+aWE("unv",32);
+aWE("up",20,10,30);
+aWE("updat",0,7,43,46);
+aWE("updateobjbrows",58,63,70,76);
+aWE("upload",74);
+aWE("us",15,16,20,3,6,24,25,26,12,13,34,36,63,65,66,68,72,74,44,46,77,52,54);
+aWE("usag",17,7,63,75);
+aWE("useful",0,18,26,13,65);
+aWE("usual",44,46);
+aWE("v",15);
+aWE("valu",14,17,20,21,2,24,7,13,59,37,38,39,74,45,75);
+aWE("vari",21);
+aWE("variabl",64);
aWE("variou",0);
-aWE("ve",17);
-aWE("vector",11,12,61,70,41,46,73,48,54);
-aWE("versa",7);
-aWE("vert",61);
-aWE("vertex",14,64,67);
-aWE("vertex_",61);
-aWE("vertic",61,64,66,67);
-aWE("very",17,12,63);
-aWE("via",71,52,53);
-aWE("vic",7);
-aWE("vid",61);
-aWE("view",0,17,1,18,20,2,21,5,25,26,9,27,28,29,11,12,32,36,39,40,70,71,43,44,45,47,49,50,52,75,76,53,54);
-aWE("visibl",53);
-aWE("visual",16);
-aWE("visualiz",53);
+aWE("ve",18);
+aWE("vector",12,13,63,72,42,47,76,49,55);
+aWE("versa",8);
+aWE("vert",63);
+aWE("vertex",15,63,66,69,73);
+aWE("vertex_",63);
+aWE("vertic",63,66,68,69);
+aWE("very",18,13,65);
+aWE("via",74,53,54);
+aWE("vic",8);
+aWE("vid",63);
+aWE("view",0,18,1,19,21,2,22,6,26,27,10,28,29,30,12,13,33,37,40,41,72,74,44,45,46,48,50,51,53,78,79,54,55);
+aWE("visibl",54);
+aWE("visual",17);
+aWE("visualiz",54);
aWE("vk",2);
-aWE("volum",13,14,15,16,17,2,22,6,25,8,10,12,60,61,34,68,71,73,52,75,76);
-aWE("volume_margin",68);
-aWE("vtk",0,53);
-aWE("vxy",8,73);
-aWE("wa_margin",68);
-aWE("walk",64);
-aWE("warp",16,26,60,68,49,54);
-aWE("way",14,17,23,24,25,12,64,38,51);
-aWE("weight",45);
-aWE("well",64);
-aWE("wheth",71);
-aWE("whil",66,39);
-aWE("whit",12,55);
-aWE("whol",2,11,12,70,71,45,48);
-aWE("whos",21,25,26,37,49);
-aWE("will",13,14,0,17,1,18,19,20,2,21,22,23,6,24,7,25,26,9,28,29,30,11,12,31,33,32,59,36,61,63,34,37,64,67,39,40,70,42,71,43,44,45,47,74,49,51,52,76,54);
-aWE("window",5);
-aWE("wir",15,8,12,33,61,63,73);
-aWE("wire_polylin",61);
-aWE("wire_polyline_edg",61);
-aWE("wire_polyline_mesh",61);
-aWE("wirefram",0,65);
-aWE("wish",23,7,9,31,53);
-aWE("within",19,64,43);
-aWE("without",1,12,68,69);
-aWE("word",19);
-aWE("work",1,12,63,67);
-aWE("worst",20);
-aWE("would",17,69,43);
-aWE("ww",8);
-aWE("x",14,5,54);
-aWE("x0",61);
-aWE("y",14,5);
-aWE("y0",61);
-aWE("your",13,14,16,0,17,1,18,19,20,2,21,5,22,23,24,25,28,29,30,31,33,32,35,36,34,64,65,38,39,40,41,71,44,45,46,47,48,52,76,54);
-aWE("z",14,5);
-aWE("z0",61);
-aWE("zero",64);
-aWE("zoom",53);
+aWE("volum",14,15,16,17,18,2,23,7,26,9,11,13,61,63,35,70,74,76,53,78,79);
+aWE("volume_margin",70);
+aWE("vtk",0,54);
+aWE("vxy",9,76);
+aWE("wa_margin",70);
+aWE("walk",66);
+aWE("warp",17,27,61,70,50,55);
+aWE("way",15,18,24,25,26,13,66,39,52);
+aWE("weight",46);
+aWE("well",66);
+aWE("wheth",74);
+aWE("whil",5,68,40);
+aWE("whit",13,56);
+aWE("whol",16,2,12,13,72,74,46,49);
+aWE("whos",22,26,27,38,50);
+aWE("will",14,15,0,18,1,19,20,21,2,5,22,23,24,7,25,8,26,27,10,29,30,31,12,13,32,34,33,60,37,63,65,35,38,66,69,40,41,72,43,74,44,45,46,48,77,50,52,53,79,55);
+aWE("window",6);
+aWE("wir",16,9,13,34,63,65,76);
+aWE("wire_polylin",63);
+aWE("wire_polyline_edg",63);
+aWE("wire_polyline_mesh",63);
+aWE("wirefram",0,67);
+aWE("wish",24,8,10,32,54);
+aWE("within",20,66,44);
+aWE("without",1,13,70,71);
+aWE("word",20);
+aWE("work",1,13,65,69);
+aWE("worst",21);
+aWE("would",18,71,44);
+aWE("wrong",63);
+aWE("ww",9);
+aWE("x",15,6,63,55);
+aWE("x0",63);
+aWE("xyz",63);
+aWE("y",15,6,63);
+aWE("y0",63);
+aWE("your",14,15,17,0,18,1,19,20,21,2,22,6,23,24,25,26,29,30,31,32,34,33,36,37,35,66,67,39,40,41,42,74,45,46,47,48,49,53,79,55);
+aWE("z",15,6,63);
+aWE("z0",63);
+aWE("zero",66);
+aWE("zoom",54);
//-->
</script>
<script language="javascript" src="whtdata.js"></script>
<script language="javascript">
<!--
- aTE(1,85,"MESH module");
+ aTE(1,87,"MESH module");
aTE(2,0,"Introduction to Mesh","mesh.htm");
aTE(2,0,"Running MESH module","files/running_smesh_module.htm");
aTE(2,0,"Introduction to MESH module python interface","smesh.py_introduction.htm");
- aTE(1,17,"Creating meshes");
+ aTE(1,19,"Creating meshes");
aTE(2,0,"About meshes","files/about_meshes.htm");
aTE(2,0,"Importing and exporting meshes","files/importing_and_exporting_meshes.htm");
aTE(2,0,"Constructing meshes","files/constructing_meshes.htm");
- aTE(1,4,"Defining Algorithms");
+ aTE(1,5,"Defining Algorithms");
aTE(2,0,"Basic meshing algorithms","files/about_meshing_algorithms.htm");
aTE(2,0,"Projection Algorithms","projection_algorithms.htm");
aTE(2,0,"Radial Prism Algorithm","radial_prism.htm");
+ aTE(2,0,"Segments around Vertex Algorithm","segments_around_vertex_algorithm.htm");
aTE(2,0,"Prism 3D Algorithm","prism_3d_algorithm.htm");
aTE(1,6,"Defining hypotheses");
aTE(2,0,"About Hypotheses","files/about_hypotheses.htm");
aTE(2,0,"Netgen 2D and 3D hypotheses","netgen_2d_and_3d_hypotheses.htm");
aTE(2,0,"Additional Hypotheses","files/non_conform_mesh_allowed_hypothesis.htm");
aTE(2,0,"Constructing submeshes","files/constructing_submeshes.htm");
+ aTE(2,0,"Building Compounds","building_compounds.htm");
aTE(2,0,"Editing Meshes","files/reassigning_hypotheses_and_algorithms.htm");
- aTE(1,8,"Viewing meshes");
+ aTE(1,7,"Viewing meshes");
aTE(2,0,"Viewing meshes","about_viewing_meshes.htm");
- aTE(2,0,"VTK 3D Viewer","files/vtk_3d_viewer.htm");
aTE(2,0,"Mesh infos","files/viewing_mesh_info.htm");
aTE(2,0,"Numbering","files/displaying_nodes_numbers.htm");
aTE(2,0,"Display Mode","presentation.htm");
aTE(2,0,"Constructing groups of specific elements","files/constructing_groups_of_specific_elements.htm");
aTE(2,0,"Deleting Groups","deleting_groups.htm");
aTE(2,0,"Selection filter library","selection_filter_library.htm");
- aTE(1,23,"Modifying meshes");
+ aTE(1,24,"Modifying meshes");
aTE(2,0,"Adding nodes and elements","files/adding_nodes_and_elements.htm");
aTE(2,0,"Adding quadratic elements","adding_quadratic_nodes_and_elements.htm");
aTE(2,0,"Removing nodes and elements","files/removing_nodes_and_elements.htm");
aTE(2,0,"Merging nodes","files/merging_nodes.htm");
aTE(2,0,"Merging Elements","merge_elements.htm");
aTE(2,0,"Moving nodes","files/displacing_nodes.htm");
+ aTE(2,0,"Mesh through point","mesh_through_point.htm");
aTE(2,0,"Diagonal inversion of elements","files/diagonal_iversion_of_elements.htm");
aTE(2,0,"Uniting two triangles","files/uniting_two_triangles.htm");
aTE(2,0,"Uniting a set of triangles","files/uniting_a_set_of_triangles.htm");
aTE(2,0,"Revolution","revolution.htm");
aTE(2,0,"Pattern mapping","pattern_mapping.htm");
aTE(2,0,"Convert to/from Quadratic Mesh","convert_to_from_quadratic_mesh.htm");
- aTE(2,0,"Python interface smesh.py" ,"smeshpy_doc/namespacesmesh.html");
- aTE(1,7,"TUI Scripts");
+aTE(2,0,"Python interface smesh.py", "smeshpy_doc/namespacesmesh.html");
+ aTE(1,7,"TUI Scripts");
aTE(2,0,"Creating Meshes","constructing_meshes.htm");
aTE(2,0,"Viewing Meshes","viewing_meshes.htm");
aTE(2,0,"Defining Hypotheses","defining_hypotheses_tui.htm");
<topic name="Aspect ratio 3D" url="aspect_ratio_3d.htm" />
<topic name="Borders at multi-connection" url="borders_at_multi-connection.htm" />
<topic name="Borders at multiconnection 2D" url="borders_at_multiconnection_2d.htm" />
+<topic name="Building Compounds" url="building_compounds.htm" />
<topic name="Clipping" url="clipping.htm" />
<topic name="Constructing Meshes" url="constructing_meshes.htm" />
<topic name="Convert to/from Quadratic Mesh" url="convert_to_from_quadratic_mesh.htm" />
<topic name="Length" url="length.htm" />
<topic name="Merge Elements" url="merge_elements.htm" />
<topic name="mesh" url="mesh.htm" />
+<topic name="Mesh through point" url="mesh_through_point.htm" />
<topic name="Modifying Meshes" url="modifying_meshes.htm" />
<topic name="SALOME - SMESH - v.version: Package smesh" url="namespacesmesh.html" />
<topic name="Netgen 2D and 3D hypotheses" url="netgen_2d_and_3d_hypotheses.htm" />
<topic name="Quality Controls" url="quality_controls.htm" />
<topic name="Radial Prism" url="radial_prism.htm" />
<topic name="Revolution" url="revolution.htm" />
+<topic name="Segments around Vertex Algorithm" url="segments_around_vertex_algorithm.htm" />
<topic name="Selection filter library" url="selection_filter_library.htm" />
<topic name="smesh.py_introduction" url="smesh.py_introduction.htm" />
<topic name="Transforming Meshes" url="transforming_meshes.htm" />
<?xml version='1.0' encoding='windows-1252' ?>
<ftswdata>
-<key name="_grp"> 72, </key>
-<key name="0"> 14,19,5,6,25,8,12,57,61,63,68,43,72,73,75, </key>
-<key name="000001"> 68, </key>
-<key name="001"> 73, </key>
-<key name="0d"> 14, </key>
-<key name="1"> 17,1,18,19,20,2,21,23,6,7,26,8,27,28,29,30,11,12,57,31,32,35,36,61,64,68,39,40,70,62,43,44,72,45,47,73,49,50,51,76,54, </key>
-<key name="10"> 6,8,12,57,31,61,72,73,75, </key>
-<key name="100"> 6,8,57,68,72,73, </key>
-<key name="109"> 73, </key>
-<key name="110"> 61, </key>
-<key name="113"> 73, </key>
-<key name="12"> 61,73, </key>
-<key name="13"> 61, </key>
-<key name="130"> 61, </key>
-<key name="15"> 61,68,73, </key>
-<key name="150"> 8,61,73, </key>
-<key name="17"> 61, </key>
-<key name="180"> 61, </key>
-<key name="1d"> 13,14,15,16,19,23,6,8,11,12,60,61,63,37,67,68,69,70,72, </key>
-<key name="1e"> 61,68, </key>
-<key name="2"> 17,1,18,20,2,21,23,6,7,26,8,27,28,29,30,11,12,31,32,36,61,64,68,39,40,70,62,43,44,45,47,73,49,50,51,76,54, </key>
-<key name="20"> 6,8,57,61,68,72,73,75, </key>
-<key name="200"> 6,8,61,72, </key>
-<key name="21"> 61,73, </key>
-<key name="23"> 61,73, </key>
-<key name="24"> 73, </key>
-<key name="240"> 61, </key>
-<key name="245"> 61, </key>
-<key name="246"> 61, </key>
-<key name="25"> 73, </key>
-<key name="255"> 61, </key>
-<key name="2d"> 13,14,15,16,18,20,4,23,6,8,11,12,57,33,32,60,36,63,64,66,67,68,69,70,43,72,73,54, </key>
-<key name="3"> 14,18,20,21,23,6,7,26,8,27,28,11,12,57,31,61,63,64,68,39,40,70,62,43,44,72,45,73,49,50,75,54, </key>
-<key name="30"> 8,61,63,73, </key>
-<key name="300"> 6, </key>
-<key name="3128"> 61, </key>
-<key name="321"> 61, </key>
-<key name="3265"> 61, </key>
-<key name="3402"> 61, </key>
-<key name="35"> 57,68, </key>
-<key name="3658"> 61, </key>
-<key name="38"> 61,68,73, </key>
-<key name="39"> 61, </key>
-<key name="3d"> 13,14,15,16,0,17,1,20,2,21,23,6,25,26,8,9,27,28,29,11,12,60,63,34,66,67,68,69,39,40,70,43,72,45,49,50,76,53, </key>
-<key name="3e"> 68, </key>
-<key name="3rd"> 14, </key>
-<key name="3x3"> 61, </key>
-<key name="4"> 14,18,20,23,6,26,8,28,12,31,61,64,68,62,43,44,47,73,54, </key>
-<key name="40"> 57,61,72, </key>
-<key name="405"> 61, </key>
-<key name="406"> 61, </key>
-<key name="45"> 12,61,73, </key>
-<key name="47"> 61, </key>
-<key name="492"> 61, </key>
-<key name="493"> 61, </key>
-<key name="5"> 5,6,8,61,68,73, </key>
-<key name="50"> 8,61,73, </key>
-<key name="502"> 61, </key>
-<key name="503"> 61, </key>
-<key name="58"> 73, </key>
-<key name="5th"> 14, </key>
-<key name="6"> 2,6,8,57,61,73, </key>
-<key name="60"> 57,61,72, </key>
-<key name="66632"> 61, </key>
-<key name="69"> 73, </key>
-<key name="7"> 6,8,57,61,68, </key>
-<key name="70"> 8,61,73, </key>
-<key name="71"> 73, </key>
-<key name="72"> 73, </key>
-<key name="73"> 61, </key>
-<key name="8"> 57,61,68,73, </key>
-<key name="80"> 61,72, </key>
-<key name="800"> 6, </key>
-<key name="814"> 61, </key>
-<key name="850"> 61, </key>
-<key name="859"> 61, </key>
-<key name="89"> 73, </key>
-<key name="9"> 61,73, </key>
-<key name="90"> 73, </key>
-<key name="900"> 6,75, </key>
-<key name="91"> 73, </key>
-<key name="92"> 73, </key>
-<key name="95"> 68, </key>
-<key name="9999"> 25, </key>
-<key name="a_mesh"> 61, </key>
-<key name="a10"> 61, </key>
-<key name="a45"> 61, </key>
-<key name="aa"> 61, </key>
-<key name="abl"> 17,1,53, </key>
-<key name="abord"> 68, </key>
-<key name="aborder"> 68, </key>
-<key name="abov"> 61,45, </key>
-<key name="absent"> 51, </key>
-<key name="absolute"> 74, </key>
-<key name="abut"> 19, </key>
-<key name="acces"> 0,71,53, </key>
-<key name="accord"> 16,18,19,20,2,32,36,64,44,45,47,76,54, </key>
-<key name="account"> 13,64, </key>
-<key name="acomp"> 73, </key>
-<key name="actual"> 63,37, </key>
-<key name="ad"> 17,1,21,7,25,26,57,61,49,51, </key>
-<key name="add"> 17,1,21,23,25,26,8,30,12,57,61,68,71,72,49, </key>
-<key name="addedg"> 61, </key>
-<key name="addfac"> 61, </key>
-<key name="addition"> 26,60,61, </key>
-<key name="additional"> 13,14,23,8,37,64,42,71,45, </key>
-<key name="addnod"> 61, </key>
-<key name="addobject"> 57, </key>
-<key name="addpolygonalfac"> 61, </key>
-<key name="addpolyhedralvolum"> 61, </key>
-<key name="addtostudy"> 6,8,57,61,68,72,73,75, </key>
-<key name="addtostudyinfath"> 6,8,57,61, </key>
-<key name="addvolum"> 61, </key>
-<key name="adjacent"> 28,36,63,37,39,43,49, </key>
-<key name="adjust"> 45, </key>
-<key name="adjustabl"> 37, </key>
-<key name="advanc"> 0,52, </key>
-<key name="afilt"> 57,68, </key>
-<key name="afiltermgr"> 68, </key>
-<key name="ageomgroup"> 57, </key>
-<key name="agroup"> 57,68, </key>
-<key name="agroup1"> 57, </key>
-<key name="agroup2"> 57, </key>
-<key name="agroup3"> 57, </key>
-<key name="agroup4"> 57, </key>
-<key name="agroup5"> 57, </key>
-<key name="agroupelemid"> 57, </key>
-<key name="agroupf"> 68, </key>
-<key name="agroupmain"> 57, </key>
-<key name="agroupn"> 68, </key>
-<key name="agroupr"> 57, </key>
-<key name="agrouptool"> 57, </key>
-<key name="ai"> 19, </key>
-<key name="al"> 61, </key>
-<key name="algeady"> 67, </key>
-<key name="algo"> 8,61,68,73, </key>
-<key name="algo_local"> 6,8,73, </key>
-<key name="algo1d"> 6,8,57,61,72,73,75, </key>
-<key name="algo2d"> 6,8,61,72,73,75, </key>
-<key name="algo3d"> 6,8,72,75, </key>
-<key name="algorithm"> 13,14,15,16,0,18,23,6,24,8,12,33,60,63,34,64,66,67,69,38,43, </key>
-<key name="allow"> 13,0,1,19,21,24,7,25,26,31,33,59,35,60,63,37,64,67,41,43,45,46,48,49,51,53, </key>
-<key name="along"> 11,12,61,64,45,53, </key>
-<key name="already"> 67, </key>
-<key name="alternativ"> 23, </key>
+<key name="_grp"> 75, </key>
+<key name="0"> 15,20,6,7,26,9,13,58,63,65,70,44,75,76,78, </key>
+<key name="000001"> 70, </key>
+<key name="001"> 76, </key>
+<key name="0d"> 15,73, </key>
+<key name="1"> 18,1,19,20,21,2,22,24,7,8,27,9,28,29,30,31,12,13,58,32,33,36,62,37,63,66,70,40,41,72,64,44,45,75,46,48,76,50,51,52,79,55, </key>
+<key name="10"> 7,9,13,58,32,63,75,76,78, </key>
+<key name="100"> 7,9,58,63,70,75,76, </key>
+<key name="109"> 76, </key>
+<key name="110"> 63, </key>
+<key name="113"> 76, </key>
+<key name="12"> 63,76, </key>
+<key name="13"> 63, </key>
+<key name="130"> 63, </key>
+<key name="15"> 63,70,76, </key>
+<key name="150"> 9,63,76, </key>
+<key name="17"> 63, </key>
+<key name="180"> 63, </key>
+<key name="1d"> 14,15,16,17,20,24,7,9,12,13,61,63,65,38,69,70,71,72,75, </key>
+<key name="1e"> 63,70, </key>
+<key name="2"> 18,1,19,21,2,22,24,7,8,27,9,28,29,30,31,12,13,32,33,62,37,63,66,70,40,41,72,64,44,45,46,48,76,50,51,52,79,55, </key>
+<key name="20"> 7,9,58,63,70,75,76,78, </key>
+<key name="200"> 7,9,63,75, </key>
+<key name="21"> 63,76, </key>
+<key name="23"> 63,76, </key>
+<key name="24"> 76, </key>
+<key name="240"> 63, </key>
+<key name="245"> 63, </key>
+<key name="246"> 63, </key>
+<key name="25"> 76, </key>
+<key name="255"> 63, </key>
+<key name="2d"> 14,15,16,17,19,21,4,24,7,9,12,13,58,34,33,61,37,65,66,68,69,70,71,72,44,75,76,55, </key>
+<key name="3"> 15,19,21,22,24,7,8,27,9,28,29,12,13,58,32,62,63,65,66,70,40,41,72,64,44,45,75,46,76,50,51,78,55, </key>
+<key name="30"> 9,63,65,76, </key>
+<key name="300"> 7, </key>
+<key name="3128"> 63, </key>
+<key name="321"> 63, </key>
+<key name="3265"> 63, </key>
+<key name="3402"> 63, </key>
+<key name="35"> 58,70, </key>
+<key name="3658"> 63, </key>
+<key name="38"> 63,70,76, </key>
+<key name="39"> 63, </key>
+<key name="3d"> 14,15,16,17,0,18,1,21,2,22,24,7,26,27,9,10,28,29,30,12,13,61,65,35,68,69,70,71,40,41,72,44,75,46,50,51,79,54, </key>
+<key name="3e"> 70, </key>
+<key name="3rd"> 15, </key>
+<key name="3x3"> 63, </key>
+<key name="4"> 15,19,21,24,7,27,9,29,13,32,62,63,66,70,64,44,45,48,76,55, </key>
+<key name="40"> 58,63,75, </key>
+<key name="405"> 63, </key>
+<key name="406"> 63, </key>
+<key name="45"> 13,63,76, </key>
+<key name="47"> 63, </key>
+<key name="492"> 63, </key>
+<key name="493"> 63, </key>
+<key name="5"> 6,7,9,63,70,76, </key>
+<key name="50"> 9,63,76, </key>
+<key name="502"> 63, </key>
+<key name="503"> 63, </key>
+<key name="58"> 76, </key>
+<key name="5th"> 15, </key>
+<key name="6"> 2,7,9,58,63,76, </key>
+<key name="60"> 58,63,75, </key>
+<key name="66632"> 63, </key>
+<key name="69"> 76, </key>
+<key name="7"> 7,9,58,63,70, </key>
+<key name="70"> 9,63,76, </key>
+<key name="71"> 76, </key>
+<key name="72"> 76, </key>
+<key name="73"> 63, </key>
+<key name="8"> 58,63,70,76, </key>
+<key name="80"> 63,75, </key>
+<key name="800"> 7, </key>
+<key name="814"> 63, </key>
+<key name="850"> 63, </key>
+<key name="859"> 63, </key>
+<key name="89"> 76, </key>
+<key name="9"> 63,76, </key>
+<key name="90"> 76, </key>
+<key name="900"> 7,78, </key>
+<key name="91"> 76, </key>
+<key name="92"> 76, </key>
+<key name="95"> 70, </key>
+<key name="9999"> 26, </key>
+<key name="a_mesh"> 63, </key>
+<key name="a10"> 63, </key>
+<key name="a45"> 63, </key>
+<key name="aa"> 63, </key>
+<key name="abl"> 18,1,54, </key>
+<key name="abord"> 70, </key>
+<key name="aborder"> 70, </key>
+<key name="abov"> 63,46, </key>
+<key name="absent"> 52, </key>
+<key name="absolute"> 77, </key>
+<key name="abut"> 20, </key>
+<key name="acces"> 0,74,54, </key>
+<key name="accord"> 17,19,20,21,2,33,37,66,45,46,48,79,55, </key>
+<key name="account"> 14,66, </key>
+<key name="acomp"> 76, </key>
+<key name="actual"> 65,38, </key>
+<key name="ad"> 18,1,22,8,26,27,58,63,50,52, </key>
+<key name="add"> 18,1,22,24,26,27,9,31,13,58,63,70,74,75,50, </key>
+<key name="addedg"> 63, </key>
+<key name="addfac"> 63, </key>
+<key name="addition"> 27,61,63, </key>
+<key name="additional"> 14,15,24,9,38,66,43,74,46, </key>
+<key name="addnod"> 63, </key>
+<key name="addobject"> 58, </key>
+<key name="addpolygonalfac"> 63, </key>
+<key name="addpolyhedralvolum"> 63, </key>
+<key name="addtostudy"> 7,9,58,63,70,75,76,78, </key>
+<key name="addtostudyinfath"> 7,9,58,63, </key>
+<key name="addvolum"> 63, </key>
+<key name="adjacent"> 29,37,65,38,40,44,50, </key>
+<key name="adjust"> 46, </key>
+<key name="adjustabl"> 38, </key>
+<key name="advanc"> 0,53, </key>
+<key name="afilt"> 58,70, </key>
+<key name="afiltermgr"> 70, </key>
+<key name="ageomgroup"> 58, </key>
+<key name="agroup"> 58,70, </key>
+<key name="agroup1"> 58, </key>
+<key name="agroup2"> 58, </key>
+<key name="agroup3"> 58, </key>
+<key name="agroup4"> 58, </key>
+<key name="agroup5"> 58, </key>
+<key name="agroupelemid"> 58, </key>
+<key name="agroupf"> 70, </key>
+<key name="agroupmain"> 58, </key>
+<key name="agroupn"> 70, </key>
+<key name="agroupr"> 58, </key>
+<key name="agrouptool"> 58, </key>
+<key name="ai"> 20, </key>
+<key name="al"> 63, </key>
+<key name="algeady"> 69, </key>
+<key name="algo"> 9,63,70,76, </key>
+<key name="algo_local"> 7,9,76, </key>
+<key name="algo1d"> 7,9,58,63,75,76,78, </key>
+<key name="algo2d"> 7,9,63,75,76,78, </key>
+<key name="algo3d"> 7,9,75,78, </key>
+<key name="algorithm"> 14,15,16,17,0,19,24,7,25,9,13,34,61,65,35,66,68,69,71,39,73,44, </key>
+<key name="allow"> 14,16,0,1,20,5,22,25,8,26,27,32,34,60,36,61,62,65,38,66,69,42,73,44,46,47,49,50,52,54, </key>
+<key name="along"> 12,13,63,66,46,54, </key>
+<key name="already"> 69, </key>
+<key name="alternativ"> 24, </key>
<key name="alternative"> 0,1, </key>
-<key name="alway"> 45, </key>
-<key name="amesh"> 6, </key>
+<key name="alway"> 46, </key>
+<key name="amesh"> 7, </key>
<key name="amount"> 3, </key>
-<key name="analytic"> 19, </key>
-<key name="angl"> 16,5,26,12,60,36,61,68,70,41,44,73,49,54, </key>
-<key name="angle270"> 73, </key>
-<key name="angle45"> 61, </key>
-<key name="angularity"> 12, </key>
-<key name="anid"> 57,68, </key>
-<key name="anoth"> 15,37,67, </key>
-<key name="any"> 14,1,23,25,28,12,57,64,69,45, </key>
-<key name="ap"> 15,17,1,18,20,2,21,5,23,7,25,26,8,9,27,28,30,11,12,32,59,60,36,61,64,67,38,39,40,70,43,44,45,46,47,49,50,51,76,54, </key>
-<key name="api"> 72, </key>
-<key name="apparent"> 23, </key>
-<key name="appear"> 0,17,1,21,23,24,7,26,27,28,30,11,12,35,64,67,39,40,70,41,46,48,49,50,51, </key>
-<key name="append"> 61, </key>
-<key name="appli"> 18,19,20,2,23,24,33,32,36,34,37,69,38,71,44,45,47,76,54, </key>
-<key name="applicabl"> 20,71, </key>
-<key name="application"> 16,64, </key>
-<key name="apply"> 13,0,23,24,25, </key>
-<key name="applytomeshfac"> 61, </key>
-<key name="appropriat"> 23, </key>
-<key name="approximate"> 19, </key>
-<key name="ar_margin"> 68, </key>
-<key name="arc"> 8,73, </key>
-<key name="arcsin"> 54, </key>
-<key name="area"> 13,16,18,8,57,33,60,34,68,45,47,53, </key>
-<key name="area_margin"> 68, </key>
-<key name="arithmetic"> 13,19,6,8,60, </key>
-<key name="arithmetic1d"> 6,8,73, </key>
-<key name="around"> 5,12,70,53, </key>
-<key name="array_of_nodes_group"> 73, </key>
-<key name="asmeshgroup1"> 57, </key>
-<key name="asmeshgroup2"> 57, </key>
-<key name="aspect"> 16,20,2,60,68,45, </key>
-<key name="assemb"> 72, </key>
-<key name="assign"> 19,23,25,8,38,54, </key>
-<key name="associat"> 17,29,39, </key>
-<key name="attribut"> 25, </key>
-<key name="auto"> 5, </key>
-<key name="automatic"> 13,19,23,60,64, </key>
-<key name="automatical"> 0,19,21,23,26,28,49, </key>
-<key name="availabl"> 43,53, </key>
-<key name="averag"> 13,19,8,33,60,64,54, </key>
-<key name="ax"> 53, </key>
-<key name="axi"> 11,61,70,41,46,73,53,54, </key>
-<key name="axisstruct"> 61,73, </key>
-<key name="axisxyz"> 61,73, </key>
+<key name="analytic"> 20, </key>
+<key name="angl"> 17,6,27,13,61,37,63,70,72,42,45,76,50,55, </key>
+<key name="angle270"> 76, </key>
+<key name="angle45"> 63, </key>
+<key name="angularity"> 13, </key>
+<key name="anid"> 58,70, </key>
+<key name="anoth"> 16,38,69, </key>
+<key name="any"> 15,16,1,24,26,29,13,58,62,63,66,71,46, </key>
+<key name="ap"> 16,18,1,19,21,2,22,6,24,8,26,27,9,10,28,29,31,12,13,33,60,61,62,37,63,66,69,39,40,41,72,44,45,46,47,48,50,51,52,79,55, </key>
+<key name="api"> 75, </key>
+<key name="apparent"> 24, </key>
+<key name="appear"> 0,18,1,5,22,24,25,8,27,28,29,31,12,13,36,62,66,69,40,41,72,42,47,49,50,51,52, </key>
+<key name="append"> 63, </key>
+<key name="appli"> 19,20,21,2,24,25,34,33,37,35,38,71,39,73,74,45,46,48,79,55, </key>
+<key name="applicabl"> 21,74, </key>
+<key name="application"> 17,66, </key>
+<key name="apply"> 14,0,24,25,26, </key>
+<key name="applytomeshfac"> 63, </key>
+<key name="appropriat"> 24, </key>
+<key name="approximate"> 20, </key>
+<key name="ar_margin"> 70, </key>
+<key name="arc"> 9,76, </key>
+<key name="arcsin"> 55, </key>
+<key name="area"> 14,17,19,9,58,34,61,35,70,46,48,54, </key>
+<key name="area_margin"> 70, </key>
+<key name="arithmetic"> 14,20,7,9,61, </key>
+<key name="arithmetic1d"> 7,9,76, </key>
+<key name="around"> 6,13,72,73,54, </key>
+<key name="array_of_nodes_group"> 76, </key>
+<key name="asmeshgroup1"> 58, </key>
+<key name="asmeshgroup2"> 58, </key>
+<key name="aspect"> 17,21,2,61,70,46, </key>
+<key name="assemb"> 75, </key>
+<key name="assign"> 16,20,24,26,9,39,55, </key>
+<key name="associat"> 18,30,40, </key>
+<key name="attribut"> 26, </key>
+<key name="auto"> 6, </key>
+<key name="automatic"> 14,20,24,61,62,66, </key>
+<key name="automatical"> 0,20,22,24,27,29,50, </key>
+<key name="automaticlength"> 63, </key>
+<key name="availabl"> 44,54, </key>
+<key name="averag"> 14,20,9,34,61,66,55, </key>
+<key name="ax"> 54, </key>
+<key name="axi"> 12,63,72,42,47,76,54,55, </key>
+<key name="axisstruct"> 63,76, </key>
+<key name="axisxyz"> 63,76, </key>
<key name="background"> 0, </key>
-<key name="bar"> 16, </key>
-<key name="bas"> 13,18,8,12,60,54, </key>
-<key name="basi"> 14,23,24, </key>
-<key name="basic"> 13,15,0, </key>
-<key name="bb"> 61, </key>
-<key name="be"> 67, </key>
-<key name="becom"> 63,64, </key>
-<key name="befor"> 71,73, </key>
-<key name="begin"> 19,43, </key>
-<key name="belong"> 3,4,25,55,56,67,43,51, </key>
-<key name="below"> 61,63,72, </key>
-<key name="berder"> 43, </key>
-<key name="bet"> 20, </key>
-<key name="binary"> 71, </key>
-<key name="bisect"> 54, </key>
-<key name="bisector"> 54, </key>
-<key name="bit"> 71, </key>
+<key name="bar"> 17, </key>
+<key name="bas"> 14,19,9,13,61,55, </key>
+<key name="basi"> 15,24,25, </key>
+<key name="basic"> 14,16,0, </key>
+<key name="bb"> 63, </key>
+<key name="be"> 69, </key>
+<key name="becom"> 5,65,66, </key>
+<key name="befor"> 74,76, </key>
+<key name="begin"> 20,44, </key>
+<key name="belong"> 3,4,26,56,57,69,44,52, </key>
+<key name="below"> 63,65,75, </key>
+<key name="berder"> 44, </key>
+<key name="bet"> 21, </key>
+<key name="binary"> 74, </key>
+<key name="bisect"> 55, </key>
+<key name="bisector"> 55, </key>
+<key name="bit"> 74, </key>
<key name="black"> 0, </key>
<key name="blu"> 3, </key>
-<key name="bmp"> 0,53, </key>
-<key name="bog"> 19, </key>
-<key name="boolean"> 61,51, </key>
-<key name="bord"> 43,73, </key>
-<key name="border"> 16,3,4,55,56,60,68,43,73, </key>
-<key name="both"> 0,12,69,45,51, </key>
-<key name="bottom"> 61,42, </key>
-<key name="bound"> 14,64,53, </key>
-<key name="boundari"> 64, </key>
-<key name="boundary"> 13,25,64,43,45, </key>
-<key name="box"> 17,1,19,21,23,6,24,7,26,8,27,28,30,11,12,57,31,59,35,63,64,67,68,39,40,70,41,42,71,43,72,45,46,73,48,49,50,51,52,75,53, </key>
-<key name="box_1"> 61, </key>
-<key name="box_cyl"> 72, </key>
-<key name="box1"> 68,73, </key>
-<key name="box2"> 68,73, </key>
-<key name="broken"> 1,37, </key>
-<key name="brown"> 25, </key>
-<key name="brows"> 0,17,1,22,23,24,25,9,30,65,39,40,71,52, </key>
-<key name="build"> 8,11,33,61,63,37,64,66,70,72, </key>
-<key name="built"> 20,24,12,64,45, </key>
-<key name="button"> 17,1,18,20,2,21,5,23,24,7,25,26,9,27,28,30,11,12,31,32,36,64,67,38,39,40,70,41,71,43,44,45,46,47,48,49,50,51,52,76,53,54, </key>
-<key name="cad"> 14, </key>
-<key name="cal"> 64, </key>
-<key name="calculat"> 16,20,2,33,47, </key>
-<key name="calculation"> 13,18,32,36, </key>
-<key name="careful"> 39, </key>
-<key name="cas"> 17,23,6,8,28,12,64,52, </key>
-<key name="caviti"> 15, </key>
-<key name="cc"> 61, </key>
-<key name="cel"> 25,63,39,50, </key>
-<key name="cent"> 12,45,53, </key>
-<key name="central"> 12, </key>
-<key name="centroid"> 45, </key>
-<key name="centroidal"> 45, </key>
-<key name="centroidal_smooth"> 61, </key>
-<key name="certain"> 25,64, </key>
-<key name="chang"> 0,19,21,6,28,61,37,38,53, </key>
-<key name="characteristic"> 16, </key>
-<key name="characteriz"> 14, </key>
-<key name="check"> 25,63,43,53, </key>
-<key name="checkbox"> 17,63,71,48, </key>
-<key name="choic"> 13,23,64, </key>
-<key name="choos"> 17,1,18,20,2,21,22,7,25,26,9,27,28,10,29,11,12,31,32,35,36,64,39,40,70,41,42,71,43,44,46,47,48,49,50,76,53,54, </key>
-<key name="chosen"> 20,26,33,34,49, </key>
-<key name="circl"> 12,73, </key>
-<key name="circlemesh"> 73, </key>
-<key name="circular"> 61, </key>
-<key name="clas"> 62, </key>
-<key name="clear"> 62,71, </key>
-<key name="click"> 0,17,1,18,20,2,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,32,36,64,65,67,38,39,40,70,42,71,43,44,45,47,49,50,51,52,76,53,54, </key>
-<key name="clip"> 0,5, </key>
-<key name="clos"> 14,20,9,12,61,43, </key>
-<key name="co"> 61,43, </key>
-<key name="coars"> 19,7,63, </key>
-<key name="coincid"> 59, </key>
-<key name="coincident"> 12,59,35, </key>
-<key name="color"> 16,0,18,20,2,25,32,36,44,47,76,53,54, </key>
-<key name="combin"> 10,32,65,71, </key>
-<key name="common"> 27,71,50, </key>
-<key name="comp"> 68, </key>
-<key name="compar"> 19,43, </key>
-<key name="complete"> 59, </key>
-<key name="complex"> 1,12, </key>
-<key name="component"> 60,42, </key>
-<key name="compos"> 13,14,15,16,0,19,2,29,33,34,69,44, </key>
-<key name="compound"> 68, </key>
-<key name="comput"> 0,19,23,6,8,57,61,64,68,43,72,73,75, </key>
-<key name="computation"> 23,24,8,61, </key>
-<key name="con"> 72, </key>
-<key name="concept"> 37, </key>
-<key name="concern"> 69, </key>
-<key name="condition"> 13,25, </key>
-<key name="confirm"> 21,26,30,39,45,49,51, </key>
-<key name="confirmation"> 25, </key>
-<key name="conform"> 13,37,43,73, </key>
-<key name="conformity"> 20, </key>
-<key name="connect"> 19,26,66,45, </key>
-<key name="connection"> 14,16,3,4,60,68, </key>
-<key name="connectivity"> 64, </key>
-<key name="consid"> 20,23, </key>
-<key name="consider"> 14,20,2,43, </key>
-<key name="consist"> 16,1,18,19,20,3,4,22,23,24,25,12,55,56,57,33,32,36,34,69,47, </key>
-<key name="consol"> 52, </key>
-<key name="constant"> 19, </key>
-<key name="construct"> 15,19,22,23,6,24,38, </key>
-<key name="construction"> 19,23,6,24, </key>
-<key name="contain"> 14,15,21,23,24,25,26,12,31,33,64,45,49, </key>
-<key name="content"> 9,53, </key>
-<key name="continu"> 45, </key>
-<key name="contour"> 14,43, </key>
-<key name="contrast"> 49, </key>
-<key name="control"> 16,0,18,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54, </key>
-<key name="converg"> 45, </key>
-<key name="conversion"> 19,7, </key>
-<key name="convert"> 7, </key>
-<key name="coordinat"> 14,17,28,64,53, </key>
-<key name="copy"> 41,71,46,73,48, </key>
-<key name="corn"> 1,54, </key>
-<key name="corner"> 26,12,45,54, </key>
-<key name="correspond"> 14,16,31,64,68,71,43,48, </key>
-<key name="cos_bot"> 61, </key>
-<key name="cos_top"> 61, </key>
-<key name="cosal"> 61, </key>
-<key name="cot"> 72, </key>
-<key name="could"> 14,17,67, </key>
-<key name="count"> 43, </key>
-<key name="counterclockwis"> 64, </key>
-<key name="cours"> 23, </key>
-<key name="cover"> 12, </key>
-<key name="creat"> 14,0,17,1,19,5,23,6,24,25,8,30,57,35,60,61,63,37,64,67,68,38,41,71,72,46,73,48,51,75,54, </key>
-<key name="createemptygroup"> 57,68, </key>
-<key name="createfiltermanag"> 68, </key>
-<key name="creategroup"> 57,61,68,72, </key>
-<key name="createpolyedr"> 73, </key>
-<key name="createpolygon"> 73, </key>
-<key name="creation"> 14,37,64,38,62,72,51, </key>
-<key name="criteria"> 60,71, </key>
-<key name="criterion"> 18,20,2,25,26,57,58,32,36,68,71,44,47,49,76,54, </key>
-<key name="cros"> 0,5,54, </key>
-<key name="cubic"> 15, </key>
-<key name="current"> 21,23,26,63,67,38,71,43,49, </key>
-<key name="curv"> 14,19,12,61, </key>
-<key name="curvilinear"> 19,12, </key>
-<key name="custom"> 63, </key>
-<key name="cut"> 19,6,26,8,57,61,51, </key>
-<key name="cutgroup"> 57, </key>
-<key name="cyl"> 8,72, </key>
-<key name="cylind"> 8,72, </key>
-<key name="d"> 19, </key>
-<key name="data"> 62, </key>
-<key name="dd"> 61, </key>
-<key name="dea"> 31, </key>
-<key name="deal"> 14, </key>
-<key name="def"> 6,61,62, </key>
-<key name="default"> 0,23,12,57,63,65,71,74,53, </key>
-<key name="defin"> 14,15,1,19,20,5,23,6,24,25,8,12,61,63,37,64,66,67,62,43,72,73,53, </key>
-<key name="definit"> 14,16,19,21,22,25,26,60,38,39,49, </key>
-<key name="definition"> 0,19,6,12,33,63,34, </key>
-<key name="deflection"> 13,19,8,60, </key>
-<key name="deflection1d"> 8, </key>
-<key name="deform"> 53, </key>
-<key name="degre"> 20,5, </key>
-<key name="delet"> 9,56,61,39,71, </key>
-<key name="deletediag"> 61, </key>
-<key name="deletion"> 39,50, </key>
-<key name="density"> 19, </key>
-<key name="depend"> 13,14,23,33,34, </key>
-<key name="describ"> 14,15,64, </key>
-<key name="description"> 64, </key>
-<key name="desirabl"> 35, </key>
-<key name="desktop"> 42, </key>
-<key name="destin"> 14,16,60,62, </key>
-<key name="detail"> 13,15,0, </key>
-<key name="detalization"> 63, </key>
-<key name="detect"> 35, </key>
-<key name="dh"> 61, </key>
-<key name="di1"> 72, </key>
-<key name="diagonal"> 26,27,61,47, </key>
-<key name="dialog"> 17,1,19,21,23,24,7,26,27,28,30,11,12,31,59,35,64,67,39,40,70,41,43,45,46,48,49,50,51, </key>
-<key name="diamet"> 20, </key>
-<key name="dif"> 1,63, </key>
-<key name="differ"> 19, </key>
-<key name="differenc"> 12,43, </key>
-<key name="different"> 13,17,25,12,67,38,71,43, </key>
-<key name="digit"> 12, </key>
-<key name="dimension"> 14,2,23,11,63,70,52, </key>
-<key name="direct"> 14,6,43,45, </key>
-<key name="direction"> 12,64,54, </key>
-<key name="dirstruct"> 61,73, </key>
-<key name="discretiz"> 11,70, </key>
-<key name="discretization"> 14,15, </key>
-<key name="displac"> 28, </key>
-<key name="display"> 16,0,1,18,20,2,3,21,23,24,25,26,28,10,29,55,32,36,65,44,45,47,49,52,76,53,54, </key>
-<key name="distanc"> 19,5,64,53,54, </key>
-<key name="distinguish"> 25, </key>
-<key name="distortion"> 45, </key>
-<key name="distribution"> 19,69, </key>
-<key name="divid"> 19, </key>
-<key name="do"> 17, </key>
-<key name="docopy"> 73, </key>
-<key name="documentation"> 62, </key>
-<key name="domain"> 64, </key>
-<key name="don"> 14,23,12,61,37,67,53, </key>
+<key name="bmp"> 0,54, </key>
+<key name="bog"> 20, </key>
+<key name="boolean"> 63,52, </key>
+<key name="bord"> 44,76, </key>
+<key name="border"> 17,3,4,56,57,61,70,44,76, </key>
+<key name="both"> 0,13,71,46,52, </key>
+<key name="bottom"> 63,43, </key>
+<key name="bound"> 15,66,54, </key>
+<key name="boundari"> 66, </key>
+<key name="boundary"> 14,26,66,44,46, </key>
+<key name="box"> 18,1,20,5,22,24,7,25,8,27,9,28,29,31,12,13,58,32,60,36,62,63,65,66,69,70,40,41,72,42,43,73,74,44,75,46,47,76,49,50,51,52,53,78,54, </key>
+<key name="box_1"> 63, </key>
+<key name="box_cyl"> 75, </key>
+<key name="box1"> 70,76, </key>
+<key name="box2"> 70,76, </key>
+<key name="break"> 63, </key>
+<key name="broken"> 1,38, </key>
+<key name="brown"> 26, </key>
+<key name="brows"> 0,18,1,5,23,24,25,26,10,31,67,40,41,74,53, </key>
+<key name="build"> 5,9,12,34,63,65,38,66,68,72,75, </key>
+<key name="built"> 21,25,13,66,46, </key>
+<key name="button"> 18,1,19,21,2,5,22,6,24,25,8,26,27,10,28,29,31,12,13,32,33,62,37,66,69,39,40,41,72,42,74,44,45,46,47,48,49,50,51,52,53,79,54,55, </key>
+<key name="c1"> 16, </key>
+<key name="cad"> 15, </key>
+<key name="cal"> 66, </key>
+<key name="calculat"> 17,21,2,34,48, </key>
+<key name="calculation"> 14,19,33,37, </key>
+<key name="careful"> 40, </key>
+<key name="cas"> 18,5,24,7,9,29,13,62,66,53, </key>
+<key name="caviti"> 16, </key>
+<key name="cc"> 63, </key>
+<key name="cel"> 26,65,40,51, </key>
+<key name="cent"> 13,46,54, </key>
+<key name="central"> 13, </key>
+<key name="centroid"> 46, </key>
+<key name="centroidal"> 46, </key>
+<key name="centroidal_smooth"> 63, </key>
+<key name="certain"> 26,62,66,73, </key>
+<key name="chang"> 0,20,22,7,29,63,38,39,54, </key>
+<key name="characteristic"> 17, </key>
+<key name="characteriz"> 15, </key>
+<key name="check"> 26,62,63,65,44,54, </key>
+<key name="checkbox"> 18,65,74,49, </key>
+<key name="choic"> 14,24,66, </key>
+<key name="choos"> 18,1,19,21,2,5,22,23,8,26,27,10,28,29,11,30,12,13,32,33,36,62,37,66,40,41,72,42,43,73,74,44,45,47,48,49,50,51,79,54,55, </key>
+<key name="chosen"> 21,5,27,34,35,50, </key>
+<key name="circl"> 13,76, </key>
+<key name="circlemesh"> 76, </key>
+<key name="circular"> 63, </key>
+<key name="clas"> 64, </key>
+<key name="clear"> 64,74, </key>
+<key name="click"> 0,18,1,19,21,2,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,33,62,37,66,67,69,39,40,41,72,43,74,44,45,46,48,50,51,52,53,79,54,55, </key>
+<key name="clip"> 0,6, </key>
+<key name="clos"> 15,21,10,13,63,44, </key>
+<key name="closest"> 62, </key>
+<key name="co"> 63,44, </key>
+<key name="coars"> 20,8,65, </key>
+<key name="coincid"> 60, </key>
+<key name="coincident"> 5,13,60,36, </key>
+<key name="color"> 17,0,19,21,2,26,33,37,45,48,79,54,55, </key>
+<key name="combin"> 11,33,67,73,74, </key>
+<key name="combination"> 5, </key>
+<key name="common"> 28,74,51, </key>
+<key name="comp"> 70, </key>
+<key name="compar"> 20,44, </key>
+<key name="complete"> 60, </key>
+<key name="complex"> 1,13, </key>
+<key name="component"> 61,43, </key>
+<key name="compos"> 14,15,16,17,0,20,2,30,34,35,71,45, </key>
+<key name="composit"> 16, </key>
+<key name="compound"> 5,70, </key>
+<key name="compound_mesh"> 5, </key>
+<key name="comput"> 0,20,24,7,9,58,63,66,70,44,75,76,78, </key>
+<key name="computation"> 24,25,9,63, </key>
+<key name="con"> 75, </key>
+<key name="concatenat"> 5, </key>
+<key name="concept"> 38, </key>
+<key name="concern"> 71, </key>
+<key name="condition"> 14,26, </key>
+<key name="confirm"> 22,27,31,40,46,50,52, </key>
+<key name="confirmation"> 26, </key>
+<key name="conform"> 14,38,44,76, </key>
+<key name="conformity"> 21, </key>
+<key name="connect"> 20,27,68,46, </key>
+<key name="connection"> 15,17,3,4,61,70, </key>
+<key name="connectivity"> 66, </key>
+<key name="consid"> 21,24, </key>
+<key name="consider"> 15,21,2,73,44, </key>
+<key name="consist"> 17,1,19,20,21,3,4,23,24,25,26,13,56,57,58,34,33,37,35,71,48, </key>
+<key name="consol"> 53, </key>
+<key name="constant"> 20, </key>
+<key name="construct"> 16,20,23,24,7,25,39, </key>
+<key name="construction"> 20,24,7,25, </key>
+<key name="contain"> 15,16,22,24,25,26,27,13,32,34,66,46,50, </key>
+<key name="content"> 10,54, </key>
+<key name="continu"> 46, </key>
+<key name="contour"> 15,44, </key>
+<key name="contrast"> 50, </key>
+<key name="control"> 17,0,19,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55, </key>
+<key name="converg"> 46, </key>
+<key name="conversion"> 20,8, </key>
+<key name="convert"> 8, </key>
+<key name="coordinat"> 15,18,29,62,63,66,54, </key>
+<key name="copy"> 42,74,47,76,49, </key>
+<key name="corn"> 1,55, </key>
+<key name="corner"> 27,13,73,46,55, </key>
+<key name="correspond"> 15,17,32,66,70,74,44,49, </key>
+<key name="cos_bot"> 63, </key>
+<key name="cos_top"> 63, </key>
+<key name="cosal"> 63, </key>
+<key name="cot"> 75, </key>
+<key name="could"> 15,18,69, </key>
+<key name="count"> 44, </key>
+<key name="counterclockwis"> 66, </key>
+<key name="cours"> 24,73, </key>
+<key name="cover"> 13, </key>
+<key name="creat"> 15,0,18,1,20,5,6,24,7,25,26,9,31,58,36,61,62,63,65,38,66,69,70,39,42,74,75,47,76,49,52,78,55, </key>
+<key name="createemptygroup"> 58,70, </key>
+<key name="createfiltermanag"> 70, </key>
+<key name="creategroup"> 58,63,70,75, </key>
+<key name="createpolyedr"> 76, </key>
+<key name="createpolygon"> 76, </key>
+<key name="creation"> 15,62,38,66,39,64,75,52, </key>
+<key name="criteria"> 61,74, </key>
+<key name="criterion"> 19,21,2,26,27,58,59,33,37,70,74,45,48,50,79,55, </key>
+<key name="cros"> 0,6,55, </key>
+<key name="ctrl"> 5, </key>
+<key name="cubic"> 16, </key>
+<key name="current"> 22,24,27,65,69,39,74,44,50, </key>
+<key name="curv"> 15,16,20,13,63, </key>
+<key name="curvilinear"> 20,13, </key>
+<key name="custom"> 65, </key>
+<key name="cut"> 20,7,27,9,58,63,52, </key>
+<key name="cutgroup"> 58, </key>
+<key name="cyl"> 9,75, </key>
+<key name="cylind"> 9,75, </key>
+<key name="d"> 20, </key>
+<key name="data"> 64, </key>
+<key name="dd"> 63, </key>
+<key name="dea"> 32, </key>
+<key name="deal"> 15, </key>
+<key name="def"> 7,63,64, </key>
+<key name="default"> 0,24,13,58,65,67,74,77,54, </key>
+<key name="defin"> 15,16,1,20,21,5,6,24,7,25,26,9,13,62,63,65,38,66,68,69,64,73,44,75,76,54, </key>
+<key name="definit"> 15,17,20,22,23,26,27,61,39,40,50, </key>
+<key name="definition"> 0,20,7,13,34,65,35, </key>
+<key name="deflection"> 14,20,9,61, </key>
+<key name="deflection1d"> 9, </key>
+<key name="deform"> 54, </key>
+<key name="degre"> 21,6, </key>
+<key name="delet"> 10,57,63,40,74, </key>
+<key name="deletediag"> 63, </key>
+<key name="deletion"> 40,51, </key>
+<key name="density"> 20, </key>
+<key name="depend"> 14,15,24,34,35, </key>
+<key name="describ"> 15,16,0,66, </key>
+<key name="description"> 66, </key>
+<key name="desirabl"> 36, </key>
+<key name="desktop"> 43, </key>
+<key name="destin"> 15,17,61,64, </key>
+<key name="detail"> 14,16,0, </key>
+<key name="detalization"> 65, </key>
+<key name="detect"> 36, </key>
+<key name="dh"> 63, </key>
+<key name="di1"> 75, </key>
+<key name="diagonal"> 27,28,63,48, </key>
+<key name="dialog"> 18,1,20,5,22,24,25,8,27,28,29,31,12,13,32,60,36,62,66,69,40,41,72,42,44,46,47,49,50,51,52, </key>
+<key name="diamet"> 21, </key>
+<key name="dif"> 1,65, </key>
+<key name="differ"> 20, </key>
+<key name="differenc"> 13,44, </key>
+<key name="different"> 14,18,26,13,69,39,74,44, </key>
+<key name="digit"> 13, </key>
+<key name="dimension"> 15,2,24,12,65,72,73,53, </key>
+<key name="direct"> 15,7,44,46, </key>
+<key name="direction"> 13,66,55, </key>
+<key name="dirstruct"> 63,76, </key>
+<key name="discretisation"> 16, </key>
+<key name="discretiz"> 12,72, </key>
+<key name="discretization"> 15, </key>
+<key name="displac"> 29, </key>
+<key name="display"> 17,0,1,19,21,2,3,22,24,25,26,27,29,11,30,56,33,37,67,45,46,48,50,53,79,54,55, </key>
+<key name="distanc"> 20,6,66,54,55, </key>
+<key name="distinguish"> 26, </key>
+<key name="distortion"> 46, </key>
+<key name="distribution"> 20,71, </key>
+<key name="divid"> 20, </key>
+<key name="do"> 18, </key>
+<key name="docopy"> 76, </key>
+<key name="documentation"> 0,64, </key>
+<key name="doesn"> 73, </key>
+<key name="domain"> 66, </key>
+<key name="don"> 15,24,13,63,38,69,54, </key>
<key name="doubl"> 1, </key>
-<key name="downward"> 53, </key>
-<key name="dr"> 61, </key>
-<key name="drag"> 53, </key>
-<key name="drawn"> 53, </key>
-<key name="dump"> 0,53, </key>
-<key name="duplicat"> 12, </key>
-<key name="dx"> 61, </key>
-<key name="dy"> 61, </key>
-<key name="e"> 20,23,24,26,12,63,64,66,69,43,49, </key>
-<key name="e_arc"> 8, </key>
-<key name="e_straight"> 8, </key>
-<key name="e1"> 61, </key>
-<key name="easi"> 22, </key>
-<key name="easy"> 62, </key>
-<key name="edg"> 13,14,15,16,0,17,1,19,20,3,4,22,23,6,25,26,8,27,28,10,12,55,56,57,58,33,32,60,61,63,37,64,66,67,68,71,43,45,73,49,50,75,54, </key>
-<key name="edge_"> 61, </key>
-<key name="edge_bezierrr"> 61, </key>
-<key name="edge_bezierrr_mesh"> 61, </key>
-<key name="edge_circl"> 61, </key>
-<key name="edge_circle_mesh"> 61, </key>
-<key name="edge_straight"> 61, </key>
-<key name="edge_straight_mesh"> 61, </key>
-<key name="edge1"> 73, </key>
-<key name="edgeslist"> 73, </key>
-<key name="edgex"> 6,8, </key>
-<key name="edit"> 6,9,30,57,35,38, </key>
-<key name="edition"> 62,72, </key>
-<key name="ee_1"> 61, </key>
-<key name="ee_2"> 61, </key>
-<key name="ee_3"> 61, </key>
-<key name="ee_4"> 61, </key>
-<key name="ee_5"> 61, </key>
-<key name="ee_6"> 61, </key>
-<key name="ee_7"> 61, </key>
-<key name="effect"> 49, </key>
-<key name="eith"> 64,66,43, </key>
-<key name="element"> 13,14,15,16,0,17,1,18,19,20,2,4,21,22,7,25,26,8,9,27,28,29,30,11,12,56,57,33,32,59,60,36,61,63,34,37,64,66,68,39,40,70,41,71,43,44,45,46,47,73,48,49,51,52,76,54, </key>
-<key name="els"> 6,8,61,64, </key>
-<key name="empty"> 61, </key>
-<key name="enabl"> 71, </key>
-<key name="encapsulat"> 24, </key>
-<key name="encounter"> 64, </key>
-<key name="end"> 13,19,8,60,37,71,43,48, </key>
-<key name="enough"> 43, </key>
-<key name="ent"> 25,27,28,31,50, </key>
-<key name="entiti"> 14,15, </key>
-<key name="entity"> 14,0,10,71, </key>
-<key name="equal"> 19,33,64,71,43,45, </key>
-<key name="equidistant"> 19, </key>
-<key name="equilateral"> 20, </key>
+<key name="downward"> 54, </key>
+<key name="dr"> 63, </key>
+<key name="drag"> 54, </key>
+<key name="drawn"> 54, </key>
+<key name="dump"> 0,54, </key>
+<key name="duplicat"> 13, </key>
+<key name="dx"> 63, </key>
+<key name="dy"> 63, </key>
+<key name="e"> 21,24,25,27,13,65,66,68,71,73,44,50, </key>
+<key name="e_arc"> 9, </key>
+<key name="e_straight"> 9, </key>
+<key name="e1"> 63, </key>
+<key name="easi"> 23, </key>
+<key name="easy"> 64, </key>
+<key name="edg"> 14,15,16,17,0,18,1,20,21,3,4,23,24,7,26,27,9,28,29,11,13,56,57,58,59,34,33,61,63,65,38,66,68,69,70,74,44,46,76,50,51,78,55, </key>
+<key name="edge_"> 63, </key>
+<key name="edge_bezierrr"> 63, </key>
+<key name="edge_bezierrr_mesh"> 63, </key>
+<key name="edge_circl"> 63, </key>
+<key name="edge_circle_mesh"> 63, </key>
+<key name="edge_straight"> 63, </key>
+<key name="edge_straight_mesh"> 63, </key>
+<key name="edge1"> 76, </key>
+<key name="edgeslist"> 76, </key>
+<key name="edgex"> 7,9, </key>
+<key name="edit"> 7,10,31,58,36,39, </key>
+<key name="edition"> 64,75, </key>
+<key name="ee_1"> 63, </key>
+<key name="ee_2"> 63, </key>
+<key name="ee_3"> 63, </key>
+<key name="ee_4"> 63, </key>
+<key name="ee_5"> 63, </key>
+<key name="ee_6"> 63, </key>
+<key name="ee_7"> 63, </key>
+<key name="effect"> 50, </key>
+<key name="eith"> 5,62,66,68,44, </key>
+<key name="element"> 14,15,16,17,0,18,1,19,20,21,2,4,5,22,23,8,26,27,9,10,28,29,30,31,12,13,57,58,34,33,60,61,37,63,65,35,38,66,68,70,40,41,72,42,73,74,44,45,46,47,48,76,49,50,52,53,79,55, </key>
+<key name="els"> 7,9,63,66, </key>
+<key name="empty"> 63, </key>
+<key name="enabl"> 74, </key>
+<key name="encapsulat"> 25, </key>
+<key name="encounter"> 66, </key>
+<key name="end"> 14,20,9,61,38,74,44,49, </key>
+<key name="enough"> 44, </key>
+<key name="ent"> 26,28,29,32,62,51, </key>
+<key name="entiti"> 15,16, </key>
+<key name="entity"> 15,0,11,74, </key>
+<key name="equal"> 20,34,66,74,44,46, </key>
+<key name="equidistant"> 20, </key>
+<key name="equilateral"> 21, </key>
<key name="eras"> 0, </key>
-<key name="error"> 61, </key>
-<key name="etc"> 16,2,26,49, </key>
-<key name="even"> 23,33,63, </key>
-<key name="eventual"> 64, </key>
-<key name="every"> 54, </key>
-<key name="everyth"> 23, </key>
-<key name="ex21_lamp"> 72, </key>
-<key name="examin"> 12, </key>
-<key name="exampl"> 14,2,23,6,25,12,64,62,72,51, </key>
-<key name="exce"> 19, </key>
-<key name="exceed"> 45, </key>
-<key name="except"> 43,53, </key>
-<key name="exist"> 13,21,25,26,30,64,71,49, </key>
-<key name="existenc"> 23, </key>
-<key name="explod"> 61, </key>
-<key name="exponent"> 19, </key>
-<key name="export"> 0,6,31,60,53, </key>
-<key name="exportation"> 31, </key>
-<key name="exportm"> 6, </key>
-<key name="extend"> 53,54, </key>
-<key name="external"> 12, </key>
-<key name="extreme"> 19, </key>
-<key name="extremiti"> 5, </key>
-<key name="extrud"> 11,12,61,70, </key>
-<key name="extrusion"> 11,12,61,73, </key>
-<key name="extrusionalongpath"> 61,73, </key>
-<key name="extrusionsweepobject"> 61, </key>
-<key name="exy"> 8, </key>
-<key name="f"> 19,8, </key>
-<key name="f1"> 61, </key>
-<key name="f2"> 61, </key>
-<key name="f3"> 61, </key>
-<key name="f4"> 61, </key>
-<key name="f5"> 61, </key>
-<key name="fac"> 13,14,15,0,17,19,2,3,22,23,6,24,25,8,10,12,55,57,33,60,61,63,37,64,66,67,68,71,43,72,73,52,75,54, </key>
-<key name="face_1"> 61, </key>
-<key name="face_2"> 61, </key>
-<key name="face1"> 8,73, </key>
-<key name="face2"> 73, </key>
-<key name="facelist"> 68, </key>
-<key name="faceslist1"> 73, </key>
-<key name="faceslist2"> 73, </key>
-<key name="facesrotat"> 61, </key>
-<key name="factor"> 19,26, </key>
-<key name="factoryserv"> 62, </key>
-<key name="fail"> 61, </key>
-<key name="far"> 43, </key>
-<key name="fashion"> 12, </key>
-<key name="fast"> 45, </key>
-<key name="featur"> 25, </key>
-<key name="ff"> 61, </key>
-<key name="ff_1"> 61, </key>
-<key name="ff_2"> 61, </key>
-<key name="ff_3"> 61, </key>
-<key name="ff_4"> 61, </key>
-<key name="ff_5"> 61, </key>
-<key name="ff_6"> 61, </key>
-<key name="ff_7"> 61, </key>
-<key name="field"> 17,1,21,25,27,28,67,40,71,43,45,49,50, </key>
-<key name="fifth"> 43, </key>
-<key name="fil"> 6,31,64,71, </key>
-<key name="fill"> 68,69,40,43, </key>
-<key name="filt"> 21,25,26,71,49, </key>
-<key name="filter"> 25,71, </key>
-<key name="fin"> 19,63, </key>
-<key name="find"> 31,64,43, </key>
-<key name="findcoincidentnod"> 73, </key>
-<key name="findorloadcomponent"> 62, </key>
-<key name="finenes"> 19,63, </key>
-<key name="first"> 1,19,23,6,12,57,61,37,64,67,43, </key>
-<key name="firstnodeid1"> 73, </key>
-<key name="firstnodeid2"> 73, </key>
-<key name="firstnodeidonfreebord"> 73, </key>
-<key name="firstnodeidonsid"> 73, </key>
-<key name="fit"> 53, </key>
-<key name="fiv"> 61, </key>
-<key name="fix"> 14,6,8,45, </key>
-<key name="flag"> 64, </key>
-<key name="fold"> 23,24, </key>
-<key name="follow"> 13,14,17,1,2,21,23,24,7,25,26,27,28,29,30,11,12,35,61,64,67,39,40,70,41,43,45,46,48,49,50,51,52, </key>
-<key name="font"> 53, </key>
-<key name="form"> 1,27,30,64,43, </key>
-<key name="format"> 0,31,60,53, </key>
-<key name="formula"> 19,20,2, </key>
-<key name="four"> 14,20,54, </key>
-<key name="fourth"> 61, </key>
-<key name="fram"> 53, </key>
-<key name="fre"> 14,16,55,56,60,68,43,45,73, </key>
-<key name="ft_area"> 57,68, </key>
-<key name="ft_aspectratio"> 68, </key>
-<key name="ft_aspectratio3d"> 68, </key>
-<key name="ft_equalto"> 57,68, </key>
-<key name="ft_freeborder"> 68, </key>
-<key name="ft_length"> 68, </key>
-<key name="ft_length2d"> 68, </key>
-<key name="ft_lessthan"> 57,68, </key>
-<key name="ft_minimumangl"> 61,68, </key>
-<key name="ft_morethan"> 57,68, </key>
-<key name="ft_multiconnection"> 68, </key>
-<key name="ft_multiconnection2d"> 68, </key>
-<key name="ft_skew"> 68, </key>
-<key name="ft_tap"> 68, </key>
-<key name="ft_volume3d"> 68, </key>
-<key name="ft_warp"> 68, </key>
-<key name="full_netgen"> 8, </key>
-<key name="function"> 14,62, </key>
-<key name="functionaliti"> 53, </key>
-<key name="functionality"> 23,7,31,59,35,43,53, </key>
-<key name="fus"> 72, </key>
-<key name="futur"> 19, </key>
-<key name="g"> 24, </key>
-<key name="gaus"> 53, </key>
-<key name="generat"> 13,14,16,19,23,60,37,64, </key>
-<key name="generation"> 6,11,64,70,72, </key>
-<key name="geom"> 14,60, </key>
-<key name="geometric"> 14,16,8, </key>
-<key name="geometrical"> 13,14,15,19,23,24,25,33,60,34,64,67,38,41,45,46,48,52, </key>
-<key name="geometry"> 24,7,25,57,61,67,72,45, </key>
-<key name="geompy"> 6,8,57,61,68,72,73,75, </key>
-<key name="get"> 0,5,23,8,12,57,64,52, </key>
-<key name="getedgenearpoint"> 6,8, </key>
-<key name="geterrorcod"> 61, </key>
-<key name="getfilt"> 57,68, </key>
-<key name="getfreeborder"> 68, </key>
-<key name="getidsfromfilt"> 57,68, </key>
-<key name="getlistofid"> 57, </key>
-<key name="getmesh"> 6,61, </key>
-<key name="getnam"> 62, </key>
-<key name="getpattern"> 61, </key>
-<key name="ghs3d"> 62, </key>
-<key name="giv"> 71,52, </key>
-<key name="given"> 19,33,61,43, </key>
-<key name="global"> 8,53, </key>
-<key name="glu"> 68, </key>
-<key name="good"> 6,45, </key>
-<key name="got"> 64, </key>
-<key name="graduat"> 53, </key>
+<key name="error"> 63, </key>
+<key name="etc"> 17,2,27,50, </key>
+<key name="even"> 16,24,34,65, </key>
+<key name="eventual"> 66, </key>
+<key name="every"> 55, </key>
+<key name="everyth"> 24, </key>
+<key name="ex21_lamp"> 75, </key>
+<key name="examin"> 13, </key>
+<key name="exampl"> 15,2,5,24,7,26,13,66,64,75,52, </key>
+<key name="exce"> 20, </key>
+<key name="exceed"> 46, </key>
+<key name="except"> 44,54, </key>
+<key name="exist"> 14,5,22,26,27,31,62,66,74,50, </key>
+<key name="existenc"> 24, </key>
+<key name="explod"> 63, </key>
+<key name="exponent"> 20, </key>
+<key name="export"> 0,7,32,61,54, </key>
+<key name="exportation"> 32, </key>
+<key name="exportm"> 7, </key>
+<key name="extend"> 54,55, </key>
+<key name="external"> 13, </key>
+<key name="extreme"> 20, </key>
+<key name="extremiti"> 6, </key>
+<key name="extrud"> 12,13,63,72, </key>
+<key name="extrusion"> 12,13,63,76, </key>
+<key name="extrusionalongpath"> 63,76, </key>
+<key name="extrusionsweepobject"> 63, </key>
+<key name="exy"> 9, </key>
+<key name="f"> 20,9, </key>
+<key name="f1"> 63, </key>
+<key name="f2"> 63, </key>
+<key name="f3"> 63, </key>
+<key name="f4"> 63, </key>
+<key name="f5"> 63, </key>
+<key name="fac"> 14,15,16,0,18,20,2,3,23,24,7,25,26,9,11,13,56,58,34,61,63,65,38,66,68,69,70,74,44,75,76,53,78,55, </key>
+<key name="face_1"> 63, </key>
+<key name="face_2"> 63, </key>
+<key name="face1"> 9,76, </key>
+<key name="face2"> 76, </key>
+<key name="facelist"> 70, </key>
+<key name="faceslist1"> 76, </key>
+<key name="faceslist2"> 76, </key>
+<key name="facesrotat"> 63, </key>
+<key name="factor"> 20,27, </key>
+<key name="factoryserv"> 64, </key>
+<key name="fail"> 63, </key>
+<key name="far"> 44, </key>
+<key name="fashion"> 13, </key>
+<key name="fast"> 46, </key>
+<key name="featur"> 26, </key>
+<key name="ff"> 63, </key>
+<key name="ff_1"> 63, </key>
+<key name="ff_2"> 63, </key>
+<key name="ff_3"> 63, </key>
+<key name="ff_4"> 63, </key>
+<key name="ff_5"> 63, </key>
+<key name="ff_6"> 63, </key>
+<key name="ff_7"> 63, </key>
+<key name="field"> 18,1,22,26,28,29,69,41,74,44,46,50,51, </key>
+<key name="fifth"> 44, </key>
+<key name="fil"> 7,32,66,74, </key>
+<key name="fill"> 70,71,41,44, </key>
+<key name="filt"> 22,26,27,74,50, </key>
+<key name="filter"> 26,74, </key>
+<key name="fin"> 20,65, </key>
+<key name="find"> 32,63,66,44, </key>
+<key name="findcoincidentnod"> 76, </key>
+<key name="findnodeclosestto"> 63, </key>
+<key name="findorloadcomponent"> 64, </key>
+<key name="finenes"> 20,65, </key>
+<key name="first"> 1,20,24,7,13,58,63,38,66,69,44, </key>
+<key name="firstnodeid1"> 76, </key>
+<key name="firstnodeid2"> 76, </key>
+<key name="firstnodeidonfreebord"> 76, </key>
+<key name="firstnodeidonsid"> 76, </key>
+<key name="fit"> 54, </key>
+<key name="fiv"> 63, </key>
+<key name="fix"> 15,7,9,46, </key>
+<key name="flag"> 66, </key>
+<key name="fold"> 24,25, </key>
+<key name="follow"> 14,15,16,18,1,2,5,22,24,25,8,26,27,28,29,30,31,12,13,36,62,63,66,69,40,41,72,42,44,46,47,49,50,51,52,53, </key>
+<key name="font"> 54, </key>
+<key name="form"> 1,28,31,66,44, </key>
+<key name="format"> 0,32,61,54, </key>
+<key name="formula"> 20,21,2, </key>
+<key name="four"> 15,21,55, </key>
+<key name="fourth"> 63, </key>
+<key name="fram"> 54, </key>
+<key name="fre"> 15,17,56,57,61,70,44,46,76, </key>
+<key name="ft_area"> 58,70, </key>
+<key name="ft_aspectratio"> 70, </key>
+<key name="ft_aspectratio3d"> 70, </key>
+<key name="ft_equalto"> 58,70, </key>
+<key name="ft_freeborder"> 70, </key>
+<key name="ft_length"> 70, </key>
+<key name="ft_length2d"> 70, </key>
+<key name="ft_lessthan"> 58,70, </key>
+<key name="ft_minimumangl"> 63,70, </key>
+<key name="ft_morethan"> 58,70, </key>
+<key name="ft_multiconnection"> 70, </key>
+<key name="ft_multiconnection2d"> 70, </key>
+<key name="ft_skew"> 70, </key>
+<key name="ft_tap"> 70, </key>
+<key name="ft_volume3d"> 70, </key>
+<key name="ft_warp"> 70, </key>
+<key name="full_netgen"> 9, </key>
+<key name="function"> 15,63,64, </key>
+<key name="functionaliti"> 54, </key>
+<key name="functionality"> 24,8,32,60,36,44,54, </key>
+<key name="fus"> 75, </key>
+<key name="futur"> 20, </key>
+<key name="g"> 25, </key>
+<key name="gaus"> 54, </key>
+<key name="generat"> 14,15,17,20,24,61,38,66, </key>
+<key name="generation"> 7,12,66,72,75, </key>
+<key name="geom"> 15,61, </key>
+<key name="geometric"> 15,17,9, </key>
+<key name="geometrical"> 14,15,16,20,24,25,26,34,61,35,66,69,39,42,46,47,49,53, </key>
+<key name="geometry"> 25,8,26,58,63,69,75,46, </key>
+<key name="geompy"> 7,9,58,63,70,75,76,78, </key>
+<key name="get"> 0,6,24,9,13,58,66,53, </key>
+<key name="getedgenearpoint"> 7,9, </key>
+<key name="geterrorcod"> 63, </key>
+<key name="getfilt"> 58,70, </key>
+<key name="getfreeborder"> 70, </key>
+<key name="getidsfromfilt"> 58,70, </key>
+<key name="getlistofid"> 58, </key>
+<key name="getmesh"> 7,63, </key>
+<key name="getnam"> 64, </key>
+<key name="getnodexyz"> 63, </key>
+<key name="getpattern"> 63, </key>
+<key name="getsubmeshnodesid"> 63, </key>
+<key name="ghs3d"> 64, </key>
+<key name="giv"> 74,53, </key>
+<key name="given"> 20,34,63,44, </key>
+<key name="global"> 9,54, </key>
+<key name="glu"> 70, </key>
+<key name="good"> 7,46, </key>
+<key name="got"> 66, </key>
+<key name="graduat"> 54, </key>
<key name="graphical"> 0, </key>
-<key name="great"> 19,53, </key>
-<key name="greatest"> 20,2, </key>
-<key name="green"> 25,12, </key>
-<key name="group"> 21,22,25,26,9,30,12,57,35,60,61,68,71,72,45,48,49,51,52, </key>
-<key name="group_nam"> 72, </key>
-<key name="group1"> 51, </key>
-<key name="group12"> 51, </key>
-<key name="group12a"> 51, </key>
-<key name="group12b"> 51, </key>
-<key name="group2"> 51, </key>
-<key name="groupongeom"> 57,61, </key>
-<key name="grouprotat"> 61, </key>
-<key name="groupsmooth"> 61, </key>
-<key name="groupsofnod"> 73, </key>
-<key name="grouptri"> 61, </key>
-<key name="growth"> 63, </key>
-<key name="h"> 54, </key>
-<key name="half"> 20,54, </key>
-<key name="halv"> 5, </key>
-<key name="hasangl"> 61, </key>
-<key name="hasrefpoint"> 61, </key>
-<key name="hav"> 20,33,37,64,66, </key>
-<key name="hedron"> 61, </key>
-<key name="height"> 72,54, </key>
-<key name="helical"> 12, </key>
-<key name="help"> 16, </key>
-<key name="henc"> 64, </key>
-<key name="her"> 64, </key>
-<key name="hexa"> 8, </key>
-<key name="hexahedral"> 15,6,8, </key>
-<key name="hexahedralization"> 23, </key>
-<key name="hexahedrical"> 8, </key>
-<key name="hexahedron"> 14,15,17,2,8,61,34,66,75, </key>
-<key name="hh"> 61, </key>
-<key name="hid"> 0,53, </key>
-<key name="high"> 14, </key>
-<key name="highlight"> 3,4,21,25,26,55,56,49, </key>
-<key name="hmax"> 20, </key>
-<key name="hol"> 56,61, </key>
-<key name="hold"> 64, </key>
-<key name="hollow"> 69, </key>
-<key name="homogeneou"> 63, </key>
-<key name="how"> 15,12,63,38, </key>
-<key name="hyp"> 24,61, </key>
-<key name="hyp1"> 6, </key>
-<key name="hyp2"> 6, </key>
-<key name="hyp3"> 6, </key>
-<key name="hyp4"> 6, </key>
-<key name="hypothes"> 13,0,19,23,6,24,8,33,60,63,37,69,38, </key>
-<key name="hypothesi"> 13,19,23,6,8,33,61,34,37,38,72, </key>
-<key name="i"> 15,20,23,26,12,57,31,61,63,64,66,68,69,43,49, </key>
-<key name="icon"> 30,39,42, </key>
-<key name="id"> 0,19,21,25,26,27,28,29,11,12,57,61,70,43,45,49,50, </key>
-<key name="id_circl"> 73, </key>
-<key name="id_fac"> 8, </key>
-<key name="id_face1"> 73, </key>
-<key name="idbox"> 6,68, </key>
-<key name="idea"> 12, </key>
-<key name="idl"> 6, </key>
-<key name="idsofelement"> 61, </key>
-<key name="idsoffixednod"> 61, </key>
-<key name="idsofside1element"> 73, </key>
-<key name="idsofside2element"> 73, </key>
-<key name="if"> 14,17,5,23,6,24,7,8,11,12,57,33,61,63,37,64,67,68,38,39,70,71,43,45,49,53, </key>
-<key name="ii"> 61, </key>
-<key name="imag"> 0,12,53, </key>
-<key name="imp"> 14, </key>
-<key name="import"> 6,8,57,31,60,61,68,72,73,75, </key>
-<key name="importation"> 31, </key>
-<key name="in"> 69, </key>
-<key name="includ"> 14,52, </key>
-<key name="increas"> 6,8, </key>
-<key name="index"> 25,64, </key>
-<key name="indic"> 64, </key>
-<key name="indicat"> 67,54, </key>
-<key name="info"> 0,52,75, </key>
-<key name="information"> 14,0,6,7,30,69,52,75, </key>
-<key name="initial"> 12,61,71,46,51, </key>
-<key name="input"> 1,19, </key>
-<key name="inscrib"> 20, </key>
-<key name="insert"> 71,43, </key>
-<key name="instead"> 6,37,64, </key>
-<key name="int"> 62, </key>
-<key name="intact"> 9, </key>
-<key name="integ"> 25, </key>
-<key name="intend"> 43, </key>
-<key name="interest"> 14, </key>
-<key name="interfac"> 6,72, </key>
-<key name="intermediat"> 43, </key>
-<key name="internal"> 64,69, </key>
-<key name="intersect"> 64,51, </key>
-<key name="intersectgroup"> 57, </key>
-<key name="intersection"> 57,64,69,51, </key>
-<key name="introduc"> 13,25,37, </key>
-<key name="introduction"> 60,72, </key>
-<key name="invers"> 14,27,61, </key>
-<key name="inversediag"> 61, </key>
-<key name="inversion"> 27,61, </key>
-<key name="invisibl"> 74, </key>
-<key name="isdon"> 61, </key>
-<key name="iso"> 64, </key>
-<key name="isolin"> 64, </key>
-<key name="isometric"> 53, </key>
-<key name="isplanarfac"> 8,73, </key>
-<key name="item"> 17,1,21,22,7,26,27,28,30,11,12,31,35,64,40,70,41,43,45,46,48,49,50,51, </key>
-<key name="iteration"> 12,45, </key>
-<key name="iterativ"> 45, </key>
-<key name="iv"> 61, </key>
-<key name="j"> 15,57,68, </key>
-<key name="join"> 44, </key>
-<key name="jpeg"> 0,53, </key>
-<key name="jpg"> 0,53, </key>
-<key name="just"> 1,64,39, </key>
-<key name="k"> 15,19,20, </key>
-<key name="keep"> 12,45,46, </key>
-<key name="key"> 64, </key>
-<key name="keyboard"> 26, </key>
-<key name="know"> 64, </key>
-<key name="ko"> 61, </key>
-<key name="l"> 54, </key>
-<key name="label"> 53, </key>
-<key name="laplacian"> 45, </key>
-<key name="last"> 1,19,12,37,43, </key>
-<key name="lastnodeid1"> 73, </key>
-<key name="lastnodeid2"> 73, </key>
-<key name="lastnodeidonfreebord"> 73, </key>
-<key name="lastnodeidonsid"> 73, </key>
-<key name="lay"> 11,64,70, </key>
-<key name="layer"> 69, </key>
-<key name="lcc"> 62, </key>
-<key name="learn"> 52, </key>
-<key name="least"> 64,45, </key>
-<key name="leav"> 23,9, </key>
-<key name="left"> 0,12,64,53, </key>
-<key name="len"> 57,61,68, </key>
-<key name="length"> 13,16,19,20,6,8,58,33,32,60,68,43,53,54, </key>
-<key name="length_margin"> 68, </key>
-<key name="lengthfromedg"> 8,72,73, </key>
-<key name="les"> 71,43,45, </key>
-<key name="level"> 13,17,63, </key>
-<key name="library"> 25,71, </key>
-<key name="lik"> 17,2,29,43, </key>
-<key name="limit"> 64,43,45, </key>
-<key name="limitation"> 67, </key>
-<key name="lin"> 14,1,19,11,37,64,70,44, </key>
-<key name="linear"> 12,63, </key>
-<key name="link"> 43, </key>
-<key name="list"> 0,17,21,25,26,9,12,67,71,49, </key>
-<key name="lk"> 19, </key>
-<key name="ll"> 53, </key>
-<key name="load"> 64,71, </key>
-<key name="loadfromfac"> 61, </key>
-<key name="local"> 6,24,8,60,37, </key>
-<key name="locallength"> 8,72, </key>
-<key name="locat"> 64,43,53, </key>
-<key name="location"> 19,28,31,45, </key>
-<key name="lock"> 26,45,53, </key>
-<key name="longest"> 20, </key>
-<key name="look"> 29,12,64,71, </key>
-<key name="low"> 14,19,63, </key>
-<key name="ly"> 64, </key>
-<key name="main"> 21,26,9,12,37,64,71,49,51, </key>
-<key name="makearc"> 8,73, </key>
-<key name="makebezi"> 61, </key>
-<key name="makebox"> 6,57,68,72,73,75, </key>
-<key name="makeboxdxdydz"> 6,8,61, </key>
-<key name="makecirclethreepnt"> 61,73, </key>
-<key name="makecompound"> 68,73, </key>
-<key name="makecon"> 72, </key>
-<key name="makecylind"> 72, </key>
-<key name="makecylinderrh"> 8, </key>
-<key name="makeedg"> 8,61, </key>
-<key name="makefac"> 8,73, </key>
-<key name="makefus"> 72, </key>
-<key name="makegluefac"> 68, </key>
-<key name="makegroupbyid"> 57, </key>
-<key name="makemesh"> 61, </key>
-<key name="makepolygon"> 61, </key>
-<key name="makepolylin"> 61, </key>
-<key name="makequadmesh2"> 61, </key>
-<key name="makeshell"> 68, </key>
-<key name="makesketch"> 8, </key>
-<key name="maketranslation"> 68, </key>
-<key name="makevector"> 8,73, </key>
-<key name="makevectordxdydz"> 72, </key>
-<key name="makevertex"> 6,8,61,72,73, </key>
-<key name="makewir"> 8,73, </key>
-<key name="manag"> 13,17, </key>
-<key name="manual"> 25,63,64,53, </key>
-<key name="map"> 15,33,61,64, </key>
-<key name="mark"> 53, </key>
-<key name="mas"> 12, </key>
-<key name="math"> 61,73, </key>
-<key name="max"> 13,8,33,60,63,34,45, </key>
-<key name="maxaspectratio"> 61, </key>
-<key name="maxelementarea"> 6,8,61,68,75, </key>
-<key name="maxelementvolum"> 6,8,72,75, </key>
-<key name="maximum"> 19,8,33,63,34,44,45,52, </key>
-<key name="maxnbofiteration"> 61, </key>
-<key name="mean"> 14,63, </key>
-<key name="meaningful"> 14, </key>
-<key name="measur"> 54, </key>
-<key name="medium"> 7, </key>
-<key name="meet"> 26,49, </key>
-<key name="mefisto"> 15,8, </key>
-<key name="menu"> 17,1,19,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,35,37,64,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52, </key>
-<key name="merg"> 59,35,43,73, </key>
-<key name="mergeequalelement"> 73, </key>
-<key name="mergenod"> 73, </key>
-<key name="mesh"> 13,14,15,16,0,17,1,18,19,20,2,3,4,21,5,22,23,6,24,7,25,26,8,9,27,28,29,30,11,12,55,56,57,31,33,32,59,35,60,36,61,63,34,37,64,65,66,67,68,69,38,39,40,70,41,42,62,71,43,44,72,45,46,47,73,48,49,50,51,52,75,76,53,54, </key>
-<key name="mesh_1"> 23,61, </key>
-<key name="mesh_2"> 61, </key>
-<key name="mesh_borders_at_multi"> 68, </key>
-<key name="mesh_free_border"> 68, </key>
-<key name="mesh_length_1d"> 68, </key>
-<key name="mesh_length_2d"> 68, </key>
-<key name="mesh_nam"> 61, </key>
-<key name="mesh1d"> 61, </key>
-<key name="mesh1d_tool"> 61, </key>
-<key name="meshbox"> 6,75, </key>
-<key name="mesheditor"> 61, </key>
-<key name="meshm"> 6, </key>
-<key name="method"> 61,45, </key>
-<key name="middl"> 1,12,37, </key>
-<key name="min_angl"> 68, </key>
-<key name="minimum"> 16,19,26,60,36,63,68,43,49, </key>
-<key name="mirror"> 73, </key>
-<key name="mod"> 0,19,65, </key>
-<key name="model"> 14,60, </key>
-<key name="modification"> 14,17,1,21,7,26,27,28,30,11,12,35,60,64,39,40,70,41,43,45,46,48,49,50, </key>
-<key name="modify"> 21,26,30,61,49, </key>
-<key name="modul"> 14,15,1,19,6,25,60,42,72,53, </key>
-<key name="mous"> 0,25,53, </key>
-<key name="mov"> 28,61, </key>
-<key name="movenod"> 61, </key>
-<key name="much"> 63, </key>
-<key name="multi"> 16,3,4,60,68, </key>
-<key name="multiconnection"> 68, </key>
-<key name="must"> 23,12,64,71,43, </key>
-<key name="myelemid"> 68, </key>
-<key name="mypnt1"> 68, </key>
-<key name="mypnt2"> 68, </key>
-<key name="n"> 64,43, </key>
-<key name="n1"> 61, </key>
-<key name="n10"> 61, </key>
-<key name="n11"> 61, </key>
-<key name="n12"> 61, </key>
-<key name="n2"> 61, </key>
-<key name="n23_param"> 8, </key>
-<key name="n3"> 61, </key>
-<key name="n4"> 61, </key>
-<key name="n5"> 61, </key>
-<key name="n6"> 61, </key>
-<key name="n7"> 61, </key>
-<key name="n8"> 61, </key>
-<key name="n9"> 61, </key>
-<key name="na"> 61, </key>
-<key name="nam"> 23,6,24,25,30,57,31,61,63,67,62,71,72,51,53, </key>
-<key name="nb"> 57,61,63,68, </key>
-<key name="nb_conn"> 68, </key>
-<key name="nb_vert"> 61, </key>
-<key name="nbedg"> 6,73,75, </key>
-<key name="nbfac"> 6,75, </key>
-<key name="nbhexa"> 75, </key>
-<key name="nbnod"> 6,73,75, </key>
-<key name="nbpolygon"> 75, </key>
-<key name="nbpolyhedron"> 75, </key>
-<key name="nbprism"> 75, </key>
-<key name="nbpyramid"> 75, </key>
-<key name="nbquadrangl"> 73,75, </key>
-<key name="nbseg"> 61, </key>
-<key name="nbtetra"> 75, </key>
-<key name="nbtriangl"> 73,75, </key>
-<key name="nbvolum"> 6,73,75, </key>
-<key name="nc"> 61, </key>
-<key name="nd"> 61, </key>
-<key name="ndiagonal"> 61, </key>
-<key name="ne"> 23, </key>
-<key name="necessary"> 17,67, </key>
-<key name="need"> 69, </key>
-<key name="negativ"> 19, </key>
-<key name="neighbor"> 27,50, </key>
-<key name="netgen"> 15,6,8,63,62,72,75, </key>
-<key name="netgen_2d3d"> 8, </key>
-<key name="new"> 0,5,23,24,25,28,61,64,38,71,51, </key>
-<key name="new_id"> 61, </key>
-<key name="next"> 19,64, </key>
-<key name="nid"> 61, </key>
-<key name="nid1"> 61, </key>
-<key name="nid2"> 61, </key>
-<key name="nid3"> 61, </key>
-<key name="nid4"> 61, </key>
-<key name="no_nam"> 62, </key>
-<key name="nod"> 14,0,17,1,18,19,20,21,22,6,7,25,28,29,11,12,33,35,60,61,63,64,65,68,39,40,70,71,43,44,45,47,73,52,75,54, </key>
-<key name="nodal"> 64,45, </key>
-<key name="node_id"> 61, </key>
-<key name="nodeid1ofside1tomerg"> 73, </key>
-<key name="nodeid1ofside2tomerg"> 73, </key>
-<key name="nodeid2ofside1tomerg"> 73, </key>
-<key name="nodeid2ofside2tomerg"> 73, </key>
-<key name="nodestart"> 61, </key>
-<key name="non"> 23, </key>
-<key name="nonam"> 62, </key>
-<key name="normal"> 46,54, </key>
-<key name="normalisation"> 20, </key>
-<key name="not"> 17,20,23,25,9,12, </key>
-<key name="noth"> 25, </key>
-<key name="notic"> 14, </key>
-<key name="now"> 5,23, </key>
-<key name="nsmooth"> 61, </key>
-<key name="numb"> 13,14,15,1,19,6,25,8,11,33,60,63,64,66,69,70,43,45,73,52,75,53, </key>
-<key name="number"> 0,1,29,12, </key>
-<key name="numberofsegment"> 6,8,57,61,68,73,75, </key>
-<key name="numeric"> 26, </key>
-<key name="numerical"> 13, </key>
-<key name="nunit"> 61, </key>
-<key name="obey"> 43, </key>
-<key name="obj"> 62, </key>
-<key name="object"> 13,15,0,17,1,19,5,22,23,24,7,25,26,9,30,31,33,61,63,34,64,65,67,38,39,40,41,48,49,52,76,53, </key>
-<key name="objet"> 25, </key>
-<key name="obtain"> 17,68, </key>
-<key name="offset"> 53, </key>
-<key name="ok"> 17,1,21,5,7,26,9,27,28,30,11,12,31,61,39,40,70,43,45,49,50,51, </key>
-<key name="on"> 14,1,19,23,6,24,26,8,9,27,11,12,55,56,59,61,37,64,68,69,38,39,70,71,43,45,46,48,49,51, </key>
-<key name="onc"> 49, </key>
-<key name="onto"> 37,64, </key>
-<key name="oo"> 20, </key>
-<key name="opaqu"> 74, </key>
-<key name="open"> 68, </key>
-<key name="operat"> 13, </key>
-<key name="operation"> 15,17,18,19,20,2,3,4,21,24,25,26,9,27,28,30,11,12,55,56,31,58,33,32,59,35,60,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54, </key>
-<key name="oppos"> 66, </key>
-<key name="opposit"> 13,5,6,26,8,33,37,43,44, </key>
-<key name="optimiz"> 63, </key>
-<key name="option"> 14,0,19,46,48, </key>
-<key name="optional"> 23,12,67, </key>
-<key name="ord"> 14,21,63,64, </key>
-<key name="ordinary"> 1,37, </key>
-<key name="orientat"> 53, </key>
-<key name="orientation"> 21,5,26,61,67,49, </key>
-<key name="origin"> 53,54, </key>
-<key name="other"> 49, </key>
-<key name="otherwis"> 23,33, </key>
-<key name="our"> 23, </key>
-<key name="out"> 69,53, </key>
-<key name="outlin"> 56, </key>
-<key name="outsid"> 64, </key>
-<key name="own"> 14, </key>
-<key name="p5"> 6,8, </key>
-<key name="packag"> 6,62,72, </key>
-<key name="pag"> 15,25,30, </key>
-<key name="pair"> 19, </key>
-<key name="pan"> 53, </key>
-<key name="paramet"> 14,19,2,71,43, </key>
-<key name="parameter"> 13,0,5,8,12,63,41,43,53, </key>
-<key name="parametric"> 14,64, </key>
-<key name="parent"> 24, </key>
-<key name="part"> 61,43,45,53, </key>
-<key name="particularity"> 14, </key>
-<key name="pas"> 6,57,61,68, </key>
-<key name="path"> 12,61,71,73, </key>
-<key name="pathmesh"> 61, </key>
-<key name="pathshap"> 61, </key>
-<key name="pattern"> 61,64, </key>
-<key name="pattern_nam"> 64, </key>
-<key name="pentagonal"> 61, </key>
+<key name="great"> 20,54, </key>
+<key name="greatest"> 21,2, </key>
+<key name="green"> 26,13, </key>
+<key name="group"> 5,22,23,26,27,10,31,13,58,36,61,63,70,74,75,46,49,50,52,53, </key>
+<key name="group_nam"> 75, </key>
+<key name="group1"> 5,52, </key>
+<key name="group1_1"> 5, </key>
+<key name="group1_2"> 5, </key>
+<key name="group12"> 52, </key>
+<key name="group12a"> 52, </key>
+<key name="group12b"> 52, </key>
+<key name="group2"> 52, </key>
+<key name="groupongeom"> 58,63, </key>
+<key name="grouprotat"> 63, </key>
+<key name="groupsmooth"> 63, </key>
+<key name="groupsofnod"> 76, </key>
+<key name="grouptri"> 63, </key>
+<key name="growth"> 65, </key>
+<key name="gui"> 0, </key>
+<key name="h"> 55, </key>
+<key name="half"> 21,55, </key>
+<key name="halv"> 6, </key>
+<key name="hasangl"> 63, </key>
+<key name="hasrefpoint"> 63, </key>
+<key name="hav"> 21,34,38,66,68, </key>
+<key name="hedron"> 63, </key>
+<key name="height"> 75,55, </key>
+<key name="helical"> 13, </key>
+<key name="help"> 17, </key>
+<key name="henc"> 66, </key>
+<key name="her"> 66, </key>
+<key name="hexa"> 9, </key>
+<key name="hexahedral"> 16,7,9, </key>
+<key name="hexahedralization"> 24, </key>
+<key name="hexahedrical"> 9, </key>
+<key name="hexahedron"> 15,16,18,2,9,63,35,68,78, </key>
+<key name="hh"> 63, </key>
+<key name="hid"> 0,54, </key>
+<key name="high"> 15,73, </key>
+<key name="highlight"> 3,4,22,26,27,56,57,50, </key>
+<key name="hmax"> 21, </key>
+<key name="hol"> 57,63, </key>
+<key name="hold"> 5,66, </key>
+<key name="hollow"> 71, </key>
+<key name="homogeneou"> 65, </key>
+<key name="how"> 16,13,65,39, </key>
+<key name="hyp"> 25,63, </key>
+<key name="hyp1"> 7, </key>
+<key name="hyp2"> 7, </key>
+<key name="hyp3"> 7, </key>
+<key name="hyp4"> 7, </key>
+<key name="hypothes"> 14,16,0,20,24,7,25,9,34,61,65,38,71,39, </key>
+<key name="hypothesi"> 14,16,20,24,7,9,34,63,35,38,39,73,75, </key>
+<key name="i"> 16,21,24,27,13,58,32,63,65,66,68,70,71,73,44,50, </key>
+<key name="icon"> 31,40,43, </key>
+<key name="id"> 0,20,22,26,27,28,29,30,12,13,58,63,72,44,46,50,51, </key>
+<key name="id_circl"> 76, </key>
+<key name="id_fac"> 9, </key>
+<key name="id_face1"> 76, </key>
+<key name="idbox"> 7,70, </key>
+<key name="idea"> 13, </key>
+<key name="identical"> 5, </key>
+<key name="idl"> 7, </key>
+<key name="idsofelement"> 63, </key>
+<key name="idsoffixednod"> 63, </key>
+<key name="idsofside1element"> 76, </key>
+<key name="idsofside2element"> 76, </key>
+<key name="if"> 15,16,18,6,24,7,25,8,9,12,13,58,34,63,65,38,66,69,70,39,40,72,73,74,44,46,50,54, </key>
+<key name="ii"> 63, </key>
+<key name="imag"> 0,13,54, </key>
+<key name="imp"> 15, </key>
+<key name="implementation"> 73, </key>
+<key name="import"> 7,9,58,32,61,63,70,75,76,78, </key>
+<key name="importation"> 32, </key>
+<key name="in"> 71, </key>
+<key name="includ"> 15,53, </key>
+<key name="increas"> 7,9, </key>
+<key name="index"> 26,66, </key>
+<key name="indic"> 66, </key>
+<key name="indicat"> 62,69,55, </key>
+<key name="info"> 0,53,78, </key>
+<key name="information"> 15,0,5,7,8,31,71,53,78, </key>
+<key name="initial"> 13,63,74,47,52, </key>
+<key name="input"> 1,20, </key>
+<key name="inscrib"> 21, </key>
+<key name="insert"> 74,44, </key>
+<key name="insid"> 63, </key>
+<key name="instead"> 7,38,66, </key>
+<key name="int"> 64, </key>
+<key name="intact"> 10, </key>
+<key name="integ"> 26, </key>
+<key name="intend"> 44, </key>
+<key name="interest"> 15, </key>
+<key name="interfac"> 7,75, </key>
+<key name="intermediat"> 44, </key>
+<key name="internal"> 66,71, </key>
+<key name="intersect"> 66,52, </key>
+<key name="intersectgroup"> 58, </key>
+<key name="intersection"> 58,66,71,52, </key>
+<key name="introduc"> 14,26,38, </key>
+<key name="introduction"> 61,75, </key>
+<key name="invers"> 15,28,63, </key>
+<key name="inversediag"> 63, </key>
+<key name="inversion"> 28,63, </key>
+<key name="invisibl"> 77, </key>
+<key name="isdon"> 63, </key>
+<key name="iso"> 66, </key>
+<key name="isolin"> 66, </key>
+<key name="isometric"> 54, </key>
+<key name="isplanarfac"> 9,76, </key>
+<key name="item"> 18,1,22,23,8,27,28,29,31,12,13,32,36,62,66,41,72,42,44,46,47,49,50,51,52, </key>
+<key name="iteration"> 13,46, </key>
+<key name="iterativ"> 46, </key>
+<key name="iv"> 63, </key>
+<key name="j"> 16,58,70, </key>
+<key name="join"> 45, </key>
+<key name="jpeg"> 0,54, </key>
+<key name="jpg"> 0,54, </key>
+<key name="just"> 1,66,40, </key>
+<key name="k"> 16,20,21, </key>
+<key name="keep"> 13,46,47, </key>
+<key name="key"> 66, </key>
+<key name="keyboard"> 27, </key>
+<key name="know"> 66, </key>
+<key name="ko"> 63, </key>
+<key name="l"> 55, </key>
+<key name="label"> 54, </key>
+<key name="laplacian"> 46, </key>
+<key name="last"> 1,20,13,38,44, </key>
+<key name="lastnodeid1"> 76, </key>
+<key name="lastnodeid2"> 76, </key>
+<key name="lastnodeidonfreebord"> 76, </key>
+<key name="lastnodeidonsid"> 76, </key>
+<key name="lat"> 62, </key>
+<key name="lay"> 12,66,72, </key>
+<key name="layer"> 71, </key>
+<key name="lcc"> 64, </key>
+<key name="learn"> 53, </key>
+<key name="least"> 66,46, </key>
+<key name="leav"> 24,10, </key>
+<key name="left"> 0,13,66,54, </key>
+<key name="len"> 58,63,70, </key>
+<key name="length"> 14,17,20,21,7,9,59,34,33,61,70,44,54,55, </key>
+<key name="length_margin"> 70, </key>
+<key name="lengthfromedg"> 9,75,76, </key>
+<key name="les"> 74,44,46, </key>
+<key name="level"> 14,18,65, </key>
+<key name="library"> 26,74, </key>
+<key name="lik"> 18,2,30,44, </key>
+<key name="limit"> 66,44,46, </key>
+<key name="limitation"> 69, </key>
+<key name="lin"> 15,1,20,12,38,66,72,45, </key>
+<key name="linear"> 13,65, </key>
+<key name="link"> 44, </key>
+<key name="list"> 0,18,22,26,27,10,13,69,74,50, </key>
+<key name="lk"> 20, </key>
+<key name="ll"> 54, </key>
+<key name="load"> 66,74, </key>
+<key name="loadfromfac"> 63, </key>
+<key name="local"> 7,25,9,61,38,73, </key>
+<key name="locallength"> 9,75, </key>
+<key name="locat"> 66,44,54, </key>
+<key name="location"> 20,29,32,63,46, </key>
+<key name="lock"> 27,46,54, </key>
+<key name="longest"> 21, </key>
+<key name="look"> 30,13,66,74, </key>
+<key name="low"> 15,20,65, </key>
+<key name="ly"> 66, </key>
+<key name="main"> 16,22,27,10,13,38,66,74,50,52, </key>
+<key name="makearc"> 9,76, </key>
+<key name="makebezi"> 63, </key>
+<key name="makebox"> 7,58,70,75,76,78, </key>
+<key name="makeboxdxdydz"> 7,9,63, </key>
+<key name="makecirclethreepnt"> 63,76, </key>
+<key name="makecompound"> 70,76, </key>
+<key name="makecon"> 75, </key>
+<key name="makecylind"> 75, </key>
+<key name="makecylinderrh"> 9, </key>
+<key name="makeedg"> 9,63, </key>
+<key name="makefac"> 9,76, </key>
+<key name="makefus"> 75, </key>
+<key name="makegluefac"> 70, </key>
+<key name="makegroupbyid"> 58, </key>
+<key name="makemesh"> 63, </key>
+<key name="makepolygon"> 63, </key>
+<key name="makepolylin"> 63, </key>
+<key name="makequadmesh2"> 63, </key>
+<key name="makeshell"> 70, </key>
+<key name="makesketch"> 9, </key>
+<key name="maketranslation"> 70, </key>
+<key name="makevector"> 9,76, </key>
+<key name="makevectordxdydz"> 75, </key>
+<key name="makevertex"> 7,9,63,75,76, </key>
+<key name="makewir"> 9,76, </key>
+<key name="manag"> 14,18, </key>
+<key name="manual"> 26,62,65,66,54, </key>
+<key name="map"> 16,34,63,66, </key>
+<key name="mark"> 54, </key>
+<key name="mas"> 13, </key>
+<key name="math"> 63,76, </key>
+<key name="max"> 14,9,34,61,65,35,46, </key>
+<key name="maxaspectratio"> 63, </key>
+<key name="maxelementarea"> 7,9,63,70,78, </key>
+<key name="maxelementvolum"> 7,9,75,78, </key>
+<key name="maximum"> 20,9,34,65,35,45,46,53, </key>
+<key name="maxnbofiteration"> 63, </key>
+<key name="mean"> 15,65, </key>
+<key name="meaningful"> 15, </key>
+<key name="measur"> 55, </key>
+<key name="medium"> 8, </key>
+<key name="meet"> 27,50, </key>
+<key name="mefisto"> 16,9, </key>
+<key name="menu"> 18,1,20,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,36,62,38,66,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53, </key>
+<key name="merg"> 5,60,36,44,76, </key>
+<key name="mergeequalelement"> 76, </key>
+<key name="mergenod"> 76, </key>
+<key name="mesh"> 14,15,16,17,0,18,1,19,20,21,2,3,4,5,22,6,23,24,7,25,8,26,27,9,10,28,29,30,31,12,13,56,57,58,32,34,33,60,36,61,62,37,63,65,35,38,66,67,68,69,70,71,39,40,41,72,42,43,64,73,74,44,45,75,46,47,48,76,49,50,51,52,53,78,79,54,55, </key>
+<key name="mesh_1"> 5,24,63, </key>
+<key name="mesh_2"> 5,63, </key>
+<key name="mesh_borders_at_multi"> 70, </key>
+<key name="mesh_free_border"> 70, </key>
+<key name="mesh_length_1d"> 70, </key>
+<key name="mesh_length_2d"> 70, </key>
+<key name="mesh_nam"> 63, </key>
+<key name="mesh1d"> 63, </key>
+<key name="mesh1d_tool"> 63, </key>
+<key name="meshbox"> 7,78, </key>
+<key name="mesheditor"> 63, </key>
+<key name="meshm"> 7, </key>
+<key name="meshtopassthroughapoint"> 63, </key>
+<key name="method"> 5,62,63,46, </key>
+<key name="middl"> 1,13,38, </key>
+<key name="min_angl"> 70, </key>
+<key name="minimum"> 17,20,27,61,37,65,70,44,50, </key>
+<key name="mirror"> 76, </key>
+<key name="mod"> 0,20,67, </key>
+<key name="model"> 15,61, </key>
+<key name="modification"> 15,18,1,22,8,27,28,29,31,12,13,36,61,62,66,40,41,72,42,44,46,47,49,50,51, </key>
+<key name="modify"> 22,27,31,63,50, </key>
+<key name="modul"> 15,16,0,1,20,7,26,61,43,75,54, </key>
+<key name="mous"> 0,26,54, </key>
+<key name="mov"> 29,62,63, </key>
+<key name="movement"> 62, </key>
+<key name="movenod"> 63, </key>
+<key name="much"> 65, </key>
+<key name="multi"> 17,3,4,61,70, </key>
+<key name="multiconnection"> 70, </key>
+<key name="must"> 24,13,66,74,44, </key>
+<key name="myelemid"> 70, </key>
+<key name="mypnt1"> 70, </key>
+<key name="mypnt2"> 70, </key>
+<key name="n"> 63,66,44, </key>
+<key name="n1"> 63, </key>
+<key name="n10"> 63, </key>
+<key name="n11"> 63, </key>
+<key name="n12"> 63, </key>
+<key name="n2"> 63, </key>
+<key name="n23_param"> 9, </key>
+<key name="n3"> 63, </key>
+<key name="n4"> 63, </key>
+<key name="n5"> 63, </key>
+<key name="n6"> 63, </key>
+<key name="n7"> 63, </key>
+<key name="n8"> 63, </key>
+<key name="n9"> 63, </key>
+<key name="na"> 63, </key>
+<key name="nam"> 5,24,7,25,26,31,58,32,63,65,69,64,74,75,52,54, </key>
+<key name="namesak"> 5, </key>
+<key name="nb"> 58,63,65,70, </key>
+<key name="nb_conn"> 70, </key>
+<key name="nb_vert"> 63, </key>
+<key name="nbedg"> 7,76,78, </key>
+<key name="nbfac"> 7,78, </key>
+<key name="nbhexa"> 78, </key>
+<key name="nbnod"> 7,76,78, </key>
+<key name="nbpolygon"> 78, </key>
+<key name="nbpolyhedron"> 78, </key>
+<key name="nbprism"> 78, </key>
+<key name="nbpyramid"> 78, </key>
+<key name="nbquadrangl"> 76,78, </key>
+<key name="nbseg"> 63, </key>
+<key name="nbtetra"> 78, </key>
+<key name="nbtriangl"> 76,78, </key>
+<key name="nbvolum"> 7,76,78, </key>
+<key name="nc"> 63, </key>
+<key name="nd"> 63, </key>
+<key name="ndiagonal"> 63, </key>
+<key name="ne"> 24, </key>
+<key name="necessari"> 73, </key>
+<key name="necessary"> 18,62,69, </key>
+<key name="need"> 71, </key>
+<key name="negativ"> 20, </key>
+<key name="neighbor"> 28,51, </key>
+<key name="neighborhood"> 73, </key>
+<key name="netgen"> 16,7,9,65,64,75,78, </key>
+<key name="netgen_2d3d"> 9, </key>
+<key name="new"> 0,6,24,25,26,29,62,63,66,39,74,52, </key>
+<key name="new_id"> 63, </key>
+<key name="next"> 20,66, </key>
+<key name="nid"> 63, </key>
+<key name="nid1"> 63, </key>
+<key name="nid2"> 63, </key>
+<key name="nid3"> 63, </key>
+<key name="nid4"> 63, </key>
+<key name="no_nam"> 64, </key>
+<key name="nod"> 15,0,18,1,19,20,21,5,22,23,7,8,26,29,30,12,13,34,36,61,62,63,65,66,67,70,40,41,72,73,74,44,45,46,48,76,53,78,55, </key>
+<key name="nodal"> 66,46, </key>
+<key name="node_id"> 63, </key>
+<key name="node000"> 63, </key>
+<key name="nodeid"> 63, </key>
+<key name="nodeid1ofside1tomerg"> 76, </key>
+<key name="nodeid1ofside2tomerg"> 76, </key>
+<key name="nodeid2ofside1tomerg"> 76, </key>
+<key name="nodeid2ofside2tomerg"> 76, </key>
+<key name="nodestart"> 63, </key>
+<key name="non"> 24,63, </key>
+<key name="nonam"> 64, </key>
+<key name="normal"> 47,55, </key>
+<key name="normalisation"> 21, </key>
+<key name="not"> 18,21,24,26,10,13, </key>
+<key name="noth"> 26, </key>
+<key name="notic"> 15, </key>
+<key name="now"> 6,24, </key>
+<key name="nsmooth"> 63, </key>
+<key name="numb"> 14,15,16,1,20,7,26,9,12,34,61,65,66,68,71,72,44,46,76,53,78,54, </key>
+<key name="number"> 0,1,30,13, </key>
+<key name="numberofsegment"> 7,9,58,63,70,76,78, </key>
+<key name="numeric"> 27, </key>
+<key name="numerical"> 14, </key>
+<key name="nunit"> 63, </key>
+<key name="obey"> 44, </key>
+<key name="obj"> 64, </key>
+<key name="object"> 14,16,0,18,1,20,5,6,23,24,25,8,26,27,10,31,32,34,63,65,35,66,67,69,39,40,41,42,73,49,50,53,79,54, </key>
+<key name="objet"> 26, </key>
+<key name="obtain"> 18,70, </key>
+<key name="offset"> 54, </key>
+<key name="ok"> 18,1,22,6,8,27,10,28,29,31,12,13,32,62,63,40,41,72,44,46,50,51,52, </key>
+<key name="on"> 15,16,1,20,24,7,25,27,9,10,28,12,13,56,57,60,62,63,38,66,70,71,39,40,72,73,74,44,46,47,49,50,52, </key>
+<key name="onc"> 50, </key>
+<key name="onto"> 38,66, </key>
+<key name="oo"> 21, </key>
+<key name="opaqu"> 77, </key>
+<key name="open"> 70, </key>
+<key name="operat"> 14, </key>
+<key name="operation"> 16,18,19,20,21,2,3,4,5,22,25,26,27,10,28,29,31,12,13,56,57,32,59,34,33,60,36,61,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55, </key>
+<key name="oppos"> 68, </key>
+<key name="opposit"> 14,6,7,27,9,34,38,44,45, </key>
+<key name="optimiz"> 65, </key>
+<key name="option"> 15,0,20,47,49, </key>
+<key name="optional"> 24,13,69, </key>
+<key name="ord"> 15,22,65,66, </key>
+<key name="ordinary"> 1,38, </key>
+<key name="orientat"> 54, </key>
+<key name="orientation"> 22,6,27,63,69,50, </key>
+<key name="origin"> 54,55, </key>
+<key name="other"> 50, </key>
+<key name="otherwis"> 24,34, </key>
+<key name="our"> 24, </key>
+<key name="out"> 71,54, </key>
+<key name="outlin"> 57, </key>
+<key name="outsid"> 66, </key>
+<key name="own"> 15, </key>
+<key name="p5"> 7,9, </key>
+<key name="packag"> 7,64,75, </key>
+<key name="pag"> 16,26,31, </key>
+<key name="pair"> 20, </key>
+<key name="pan"> 54, </key>
+<key name="paramet"> 15,20,2,74,44, </key>
+<key name="parameter"> 14,0,6,9,13,65,42,44,54, </key>
+<key name="parametric"> 15,66, </key>
+<key name="parent"> 25, </key>
+<key name="part"> 63,44,46,54, </key>
+<key name="particularity"> 15, </key>
+<key name="pas"> 7,58,62,63,70, </key>
+<key name="path"> 13,63,74,76, </key>
+<key name="pathmesh"> 63, </key>
+<key name="pathshap"> 63, </key>
+<key name="pattern"> 63,66, </key>
+<key name="pattern_nam"> 66, </key>
+<key name="pentagonal"> 63, </key>
<key name="pentahedron"> 2, </key>
-<key name="per"> 63, </key>
-<key name="perform"> 60,61,40,43,46,51,53, </key>
-<key name="perimet"> 20, </key>
-<key name="permit"> 66,67, </key>
-<key name="pi"> 61,73, </key>
-<key name="pictur"> 3,25,12,55,56,59, </key>
-<key name="piec"> 72, </key>
-<key name="plac"> 7,43,53, </key>
-<key name="plan"> 5,68,46,54, </key>
-<key name="planar"> 61,54, </key>
-<key name="platform"> 25,42, </key>
-<key name="pleas"> 9,12, </key>
-<key name="plot"> 19, </key>
-<key name="plu"> 11,70, </key>
-<key name="png"> 0,53, </key>
-<key name="point"> 14,1,19,12,61,37,64,67,70,41,43,46,73,48,53,54, </key>
-<key name="pointstruct"> 61,73, </key>
-<key name="polygon"> 17,61,75, </key>
-<key name="polygonal"> 61, </key>
-<key name="polyhedral"> 17,61, </key>
-<key name="polyhedron"> 17,61,66,75, </key>
-<key name="polylin"> 12, </key>
-<key name="pop"> 9,29, </key>
-<key name="position"> 14,64,53, </key>
-<key name="posses"> 63,37, </key>
-<key name="possibility"> 71, </key>
-<key name="possibl"> 13,2,25,63,64, </key>
-<key name="post"> 53, </key>
-<key name="powerful"> 71, </key>
-<key name="precision"> 17, </key>
-<key name="preferenc"> 13,33,60,65, </key>
-<key name="prefix"> 71, </key>
-<key name="preproces"> 25, </key>
-<key name="pres"> 17,1,12,39,53, </key>
-<key name="present"> 14,0,63,51, </key>
-<key name="presentation"> 16,0,53, </key>
-<key name="preserv"> 64, </key>
-<key name="preset"> 13, </key>
-<key name="preview"> 17,5,26,64,71, </key>
-<key name="previou"> 19,12,49, </key>
-<key name="previous"> 24,25,60,64, </key>
-<key name="principl"> 12, </key>
-<key name="print"> 6,8,57,61,68,73,75, </key>
-<key name="printmeshinfo"> 6, </key>
-<key name="prism"> 66,69,75, </key>
-<key name="prism3d"> 66, </key>
-<key name="prismatic"> 15, </key>
-<key name="pro"> 53, </key>
-<key name="problem"> 6,8, </key>
-<key name="proce"> 23,9, </key>
-<key name="procedur"> 45, </key>
-<key name="proceed"> 12,38, </key>
-<key name="proces"> 45, </key>
-<key name="produc"> 14,7,11,70,45, </key>
-<key name="product"> 54, </key>
-<key name="program"> 23, </key>
-<key name="progression"> 19, </key>
-<key name="project"> 64, </key>
-<key name="projection"> 15,64,66,67,69,54, </key>
-<key name="prompt"> 19, </key>
-<key name="propagat"> 6,8,37, </key>
-<key name="propagation"> 13,6,8,37,73, </key>
-<key name="properti"> 53, </key>
-<key name="prov"> 63, </key>
-<key name="provid"> 0,17,26,72, </key>
-<key name="pseudo"> 27, </key>
-<key name="pt1"> 72, </key>
-<key name="pt2"> 72, </key>
-<key name="pul"> 45, </key>
-<key name="put"> 8, </key>
-<key name="px"> 8,73, </key>
-<key name="px1"> 73, </key>
-<key name="py"> 8,73, </key>
-<key name="py1"> 73, </key>
-<key name="pyramid"> 75, </key>
-<key name="pyramidal"> 15, </key>
-<key name="python"> 6,62,72,52, </key>
-<key name="pz"> 8,73, </key>
-<key name="pz1"> 73, </key>
-<key name="q1"> 61, </key>
+<key name="per"> 65, </key>
+<key name="perform"> 61,63,41,44,47,52,54, </key>
+<key name="perimet"> 21, </key>
+<key name="permit"> 68,69, </key>
+<key name="pi"> 63,76, </key>
+<key name="pictur"> 3,26,13,56,57,60, </key>
+<key name="piec"> 75, </key>
+<key name="plac"> 8,44,54, </key>
+<key name="plan"> 6,70,47,55, </key>
+<key name="planar"> 63,55, </key>
+<key name="platform"> 26,43, </key>
+<key name="pleas"> 10,13, </key>
+<key name="plot"> 20, </key>
+<key name="plu"> 12,72, </key>
+<key name="png"> 0,54, </key>
+<key name="point"> 15,1,20,13,62,63,38,66,69,72,42,44,47,76,49,54,55, </key>
+<key name="pointstruct"> 63,76, </key>
+<key name="polygon"> 18,63,78, </key>
+<key name="polygonal"> 63, </key>
+<key name="polyhedral"> 18,63, </key>
+<key name="polyhedron"> 18,63,68,78, </key>
+<key name="polylin"> 13, </key>
+<key name="pop"> 10,30, </key>
+<key name="position"> 15,66,54, </key>
+<key name="posses"> 65,38, </key>
+<key name="possibility"> 74, </key>
+<key name="possibl"> 14,2,5,26,65,66, </key>
+<key name="post"> 54, </key>
+<key name="powerful"> 74, </key>
+<key name="precision"> 18, </key>
+<key name="preferenc"> 14,34,61,67, </key>
+<key name="prefix"> 74, </key>
+<key name="preproces"> 26, </key>
+<key name="pres"> 18,1,13,40,54, </key>
+<key name="present"> 15,0,65,52, </key>
+<key name="presentation"> 17,0,54, </key>
+<key name="preserv"> 66, </key>
+<key name="preset"> 14, </key>
+<key name="preview"> 18,6,27,62,66,74, </key>
+<key name="previou"> 20,13,50, </key>
+<key name="previous"> 25,26,61,66, </key>
+<key name="principl"> 13, </key>
+<key name="print"> 7,9,58,63,70,76,78, </key>
+<key name="printmeshinfo"> 7, </key>
+<key name="prism"> 68,71,78, </key>
+<key name="prism3d"> 68, </key>
+<key name="prismatic"> 16, </key>
+<key name="pro"> 54, </key>
+<key name="problem"> 7,9, </key>
+<key name="proce"> 24,10, </key>
+<key name="procedur"> 46, </key>
+<key name="proceed"> 13,39, </key>
+<key name="proces"> 5,46, </key>
+<key name="produc"> 15,8,12,72,46, </key>
+<key name="product"> 55, </key>
+<key name="program"> 24, </key>
+<key name="progression"> 20, </key>
+<key name="project"> 66, </key>
+<key name="projection"> 16,66,68,69,71,55, </key>
+<key name="prompt"> 20, </key>
+<key name="propagat"> 7,9,38, </key>
+<key name="propagation"> 14,7,9,38,76, </key>
+<key name="properti"> 54, </key>
+<key name="prov"> 65, </key>
+<key name="provid"> 16,0,18,27,75, </key>
+<key name="pseudo"> 28, </key>
+<key name="pt1"> 75, </key>
+<key name="pt2"> 75, </key>
+<key name="pul"> 46, </key>
+<key name="put"> 9, </key>
+<key name="px"> 9,76, </key>
+<key name="px1"> 76, </key>
+<key name="py"> 9,76, </key>
+<key name="py1"> 76, </key>
+<key name="pyramid"> 78, </key>
+<key name="pyramidal"> 16, </key>
+<key name="python"> 7,64,75,53, </key>
+<key name="pz"> 9,76, </key>
+<key name="pz1"> 76, </key>
+<key name="q1"> 63, </key>
<key name="qi"> 2, </key>
-<key name="qk"> 20,2, </key>
-<key name="quad"> 54, </key>
-<key name="quad_1"> 61, </key>
-<key name="quad_2"> 61, </key>
-<key name="quad_3"> 61, </key>
-<key name="quad_4"> 61, </key>
-<key name="quad_5"> 61, </key>
-<key name="quad_6"> 61, </key>
-<key name="quad_7"> 61, </key>
-<key name="quadra"> 6,57, </key>
-<key name="quadrangl"> 13,14,15,17,18,20,2,6,26,8,27,11,12,57,33,32,60,36,61,63,66,69,70,44,73,75, </key>
-<key name="quadrangle"> 66, </key>
-<key name="quadrangular"> 15,6,8,33,37, </key>
-<key name="quadratic"> 13,1,7,63,37, </key>
-<key name="quadtotri"> 61, </key>
-<key name="quality"> 16,0,18,19,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54, </key>
-<key name="quantity"> 13, </key>
-<key name="r1"> 61, </key>
-<key name="radial"> 69, </key>
-<key name="radio"> 21,25,26,41,43,46,49, </key>
-<key name="radiu"> 20,61,63, </key>
-<key name="radius"> 63, </key>
-<key name="radius_1"> 72, </key>
-<key name="radius_2"> 72, </key>
-<key name="rang"> 19,25,57,61,63,68, </key>
-<key name="rat"> 63, </key>
-<key name="ratio"> 16,20,2,60,68,45,47,54, </key>
-<key name="ready"> 23, </key>
+<key name="qk"> 21,2, </key>
+<key name="quad"> 55, </key>
+<key name="quad_1"> 63, </key>
+<key name="quad_2"> 63, </key>
+<key name="quad_3"> 63, </key>
+<key name="quad_4"> 63, </key>
+<key name="quad_5"> 63, </key>
+<key name="quad_6"> 63, </key>
+<key name="quad_7"> 63, </key>
+<key name="quadra"> 7,58, </key>
+<key name="quadrangl"> 14,15,16,18,19,21,2,7,27,9,28,12,13,58,34,33,61,37,63,65,68,71,72,45,76,78, </key>
+<key name="quadrangle"> 68, </key>
+<key name="quadrangular"> 16,7,9,34,38, </key>
+<key name="quadratic"> 14,1,8,65,38, </key>
+<key name="quadtotri"> 63, </key>
+<key name="quality"> 17,0,19,20,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55, </key>
+<key name="quantity"> 14, </key>
+<key name="r1"> 63, </key>
+<key name="radial"> 71, </key>
+<key name="radio"> 22,26,27,42,44,47,50, </key>
+<key name="radiu"> 21,63,65, </key>
+<key name="radius"> 65, </key>
+<key name="radius_1"> 75, </key>
+<key name="radius_2"> 75, </key>
+<key name="rais"> 63, </key>
+<key name="rang"> 20,26,58,63,65,70, </key>
+<key name="rat"> 65, </key>
+<key name="ratio"> 17,21,2,61,70,46,48,55, </key>
+<key name="ready"> 24, </key>
<key name="recent"> 0, </key>
-<key name="red"> 56, </key>
-<key name="redefin"> 0,53, </key>
-<key name="reduc"> 45, </key>
-<key name="reevaluat"> 45, </key>
-<key name="refer"> 64, </key>
-<key name="referenc"> 14,16,23,24, </key>
-<key name="refin"> 13, </key>
-<key name="reflect"> 64,44,76, </key>
-<key name="refpoint"> 61, </key>
+<key name="red"> 57, </key>
+<key name="redefin"> 0,54, </key>
+<key name="reduc"> 46, </key>
+<key name="reevaluat"> 46, </key>
+<key name="refer"> 66, </key>
+<key name="referenc"> 15,17,24,25, </key>
+<key name="refin"> 14, </key>
+<key name="reflect"> 66,45,79, </key>
+<key name="refpoint"> 63, </key>
<key name="refresh"> 0, </key>
-<key name="regular"> 20,6,8,63,62, </key>
-<key name="relat"> 42, </key>
-<key name="relation"> 14, </key>
-<key name="relationship"> 14, </key>
-<key name="remot"> 53, </key>
-<key name="remov"> 21,6,25,26,9,30,12,57,61,68,39,71,49, </key>
-<key name="removal"> 60, </key>
-<key name="removeelement"> 61,68, </key>
-<key name="removehypothesi"> 6, </key>
-<key name="removenod"> 61, </key>
-<key name="renumb"> 40, </key>
-<key name="renumber"> 61,40, </key>
-<key name="renumbernod"> 61, </key>
-<key name="reorient"> 21,61, </key>
-<key name="replac"> 43, </key>
-<key name="represent"> 13,14,19,2,65,47,53, </key>
-<key name="representation"> 14, </key>
-<key name="requir"> 27,28,63,50, </key>
-<key name="res"> 61, </key>
-<key name="reset"> 53, </key>
-<key name="resiz"> 53, </key>
-<key name="respect"> 12, </key>
+<key name="regular"> 21,7,9,65,64, </key>
+<key name="relat"> 43, </key>
+<key name="relation"> 15, </key>
+<key name="relationship"> 15, </key>
+<key name="remot"> 54, </key>
+<key name="remov"> 22,7,26,27,10,31,13,58,63,70,40,74,50, </key>
+<key name="removal"> 61, </key>
+<key name="removeelement"> 63,70, </key>
+<key name="removehypothesi"> 7, </key>
+<key name="removenod"> 63, </key>
+<key name="renam"> 5, </key>
+<key name="renumb"> 41, </key>
+<key name="renumber"> 63,41, </key>
+<key name="renumbernod"> 63, </key>
+<key name="reorient"> 22,63, </key>
+<key name="replac"> 44, </key>
+<key name="represent"> 14,15,20,2,67,48,54, </key>
+<key name="representation"> 15, </key>
+<key name="requir"> 28,29,65,73,51, </key>
+<key name="res"> 63, </key>
+<key name="reset"> 54, </key>
+<key name="resiz"> 54, </key>
+<key name="respect"> 13, </key>
<key name="respectiv"> 1, </key>
-<key name="rest"> 64,43, </key>
-<key name="restor"> 53, </key>
-<key name="restrict"> 14, </key>
-<key name="result"> 13,17,12,57,68,45,51, </key>
-<key name="ret"> 6,8, </key>
-<key name="retriev"> 14, </key>
-<key name="return"> 58,61, </key>
-<key name="reveal"> 20, </key>
-<key name="revers"> 1,64, </key>
-<key name="revert"> 21, </key>
-<key name="revolution"> 11,61,70, </key>
-<key name="revolv"> 61,70, </key>
-<key name="right"> 0,22,9,28,29,12,65, </key>
-<key name="rotat"> 11,12,61,70,41,73,53, </key>
-<key name="rotation"> 5,70,41,73,53, </key>
-<key name="rotationsweepobject"> 61, </key>
-<key name="rough"> 13, </key>
-<key name="rr"> 61, </key>
-<key name="rul"> 19,37,43, </key>
-<key name="run"> 42, </key>
-<key name="salom"> 25,8,57,60,61,68,42,62,73, </key>
-<key name="sam"> 14,0,19,20,2,23,24,8,12,37,66,67,38,71,43,51, </key>
-<key name="sampl"> 15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54, </key>
-<key name="sav"> 71, </key>
-<key name="scal"> 19,53, </key>
-<key name="scalar"> 16, </key>
-<key name="scen"> 53, </key>
-<key name="script"> 15,17,18,19,20,2,3,4,21,23,6,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54, </key>
-<key name="se"> 15,17,18,19,20,2,3,4,21,5,6,24,7,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,66,38,39,40,70,41,43,44,72,45,46,47,48,49,50,51,76,53,54, </key>
-<key name="seam"> 64, </key>
-<key name="search"> 31,71, </key>
-<key name="second"> 17,61,63,43, </key>
-<key name="secondnodeid1"> 73, </key>
-<key name="secondnodeid2"> 73, </key>
-<key name="secondnodeidonfreebord"> 73, </key>
-<key name="section"> 0,5,23,64,72, </key>
-<key name="seg"> 63, </key>
-<key name="segment"> 13,19,6,8,57,33,60,61,63,68,72,73,75, </key>
-<key name="select"> 13,0,17,1,19,21,22,23,6,24,7,25,26,9,27,28,30,11,12,31,35,61,63,37,64,65,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52,53, </key>
-<key name="selectabl"> 59, </key>
-<key name="selection"> 17,1,21,25,26,9,71,49, </key>
-<key name="sens"> 14, </key>
-<key name="separat"> 47, </key>
-<key name="sequenc"> 43, </key>
-<key name="set"> 14,15,17,19,21,5,23,25,8,28,12,33,60,61,63,34,64,65,69,71,43,45,74,49,53, </key>
-<key name="setmaxelementarea"> 6, </key>
-<key name="setnam"> 62,72, </key>
-<key name="setting"> 23, </key>
-<key name="seven"> 12,61, </key>
-<key name="sew"> 12,43,73, </key>
-<key name="sewbordertosid"> 73, </key>
-<key name="sewconformfreeborder"> 73, </key>
-<key name="sewfreeborder"> 73, </key>
-<key name="sewsideelement"> 73, </key>
-<key name="sg"> 57,61,68,73, </key>
-<key name="shad"> 0,65,74, </key>
-<key name="shall"> 21,27,28,35,64,70,41,46,48,49,50, </key>
-<key name="shap"> 13,14,15,12,61,64,66,67,69,45, </key>
-<key name="shape_mesh"> 61, </key>
-<key name="shape1d"> 61, </key>
-<key name="shapetyp"> 6,8,57,61,68,72,73, </key>
-<key name="shel"> 69, </key>
-<key name="shell"> 68,69, </key>
-<key name="shift"> 17,1,26,39,45, </key>
-<key name="shortest"> 54, </key>
-<key name="should"> 19,7,25,11,12,64,66,69,70,41,71,43,45,51, </key>
-<key name="show"> 19,5,12,71,53, </key>
-<key name="shown"> 16,45, </key>
-<key name="shrink"> 65, </key>
-<key name="sid"> 6,8,36,63,66,43,44,73, </key>
-<key name="simp"> 23,37, </key>
-<key name="simpl"> 14,17,12,64, </key>
-<key name="simplex"> 20,2, </key>
-<key name="sin"> 61, </key>
-<key name="sin_bot"> 61, </key>
-<key name="sin_top"> 61, </key>
-<key name="six"> 12,61, </key>
-<key name="siz"> 0,63,72,45, </key>
-<key name="sk"> 20,2, </key>
-<key name="sketch"> 8, </key>
-<key name="sketcher"> 8, </key>
-<key name="sketcher1"> 8, </key>
-<key name="sketcher2"> 8, </key>
-<key name="skew"> 16,26,60,68,44,49, </key>
-<key name="skew_margin"> 68, </key>
-<key name="slid"> 74, </key>
-<key name="small"> 53, </key>
-<key name="smesh"> 6,8,57,61,68,62,43,72,73,75, </key>
-<key name="smesh_mechanic"> 57,61,68,73, </key>
-<key name="smesh_mechanic_tetra"> 68, </key>
-<key name="smeshgroup1"> 57, </key>
-<key name="smooth"> 61,45, </key>
-<key name="smoothobject"> 61, </key>
-<key name="smp"> 64, </key>
-<key name="so"> 13,19,20,12,64,43,47, </key>
-<key name="solid"> 8,60,67, </key>
-<key name="somewhat"> 17, </key>
-<key name="soon"> 6, </key>
-<key name="sort"> 21,25,26,49, </key>
-<key name="sourc"> 67,71, </key>
-<key name="spac"> 14,64,69,41,48, </key>
-<key name="specifi"> 19,3,64,39,43,45, </key>
-<key name="specific"> 15,22,71, </key>
-<key name="specify"> 17,1,26,11,12,64,39,70,41,71,45,46,48,51, </key>
-<key name="spher"> 19,20,23, </key>
-<key name="split"> 15,19,2,5,63,43, </key>
-<key name="sqrt"> 61, </key>
-<key name="standalon"> 25,57,71, </key>
-<key name="standard"> 0,7,31,72,52, </key>
-<key name="start"> 13,19,5,8,12,60,42,43,48, </key>
-<key name="startendlength"> 8, </key>
-<key name="static"> 62, </key>
-<key name="step"> 11,70, </key>
-<key name="stor"> 64,71, </key>
-<key name="str"> 62, </key>
-<key name="straight"> 1,8,12,61,37, </key>
-<key name="stretch"> 53, </key>
-<key name="strict"> 53, </key>
-<key name="structur"> 23,24,61,62, </key>
-<key name="study"> 8,57,71,72, </key>
-<key name="stuf"> 53, </key>
-<key name="styl"> 6, </key>
-<key name="sub"> 6,8,12,31,35,64,41,43,46,48, </key>
-<key name="submenu"> 17,10,39,40, </key>
-<key name="submesh"> 13,21,22,6,24,25,26,11,12,38,70,45,48,49,52, </key>
-<key name="subshapeall"> 6,8,57,61,68,73, </key>
-<key name="subshapeallid"> 72, </key>
-<key name="subshapeallsort"> 61, </key>
-<key name="subshapelist"> 6,57, </key>
-<key name="subshapenam"> 6, </key>
-<key name="succed"> 8, </key>
+<key name="rest"> 66,44, </key>
+<key name="restor"> 54, </key>
+<key name="restrict"> 15, </key>
+<key name="result"> 14,18,5,13,58,62,70,46,52, </key>
+<key name="ret"> 7,9, </key>
+<key name="retriev"> 15, </key>
+<key name="return"> 59,63, </key>
+<key name="reveal"> 21, </key>
+<key name="revers"> 1,66, </key>
+<key name="revert"> 22, </key>
+<key name="revolution"> 12,63,72, </key>
+<key name="revolv"> 63,72, </key>
+<key name="right"> 0,23,10,29,30,13,67, </key>
+<key name="rotat"> 12,13,63,72,42,76,54, </key>
+<key name="rotation"> 6,72,42,76,54, </key>
+<key name="rotationsweepobject"> 63, </key>
+<key name="rough"> 14, </key>
+<key name="rr"> 63, </key>
+<key name="rul"> 20,38,44, </key>
+<key name="run"> 43, </key>
+<key name="salom"> 26,9,58,61,63,70,43,64,76, </key>
+<key name="sam"> 15,16,0,20,21,2,24,25,9,13,38,68,69,39,74,44,52, </key>
+<key name="sampl"> 16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55, </key>
+<key name="sav"> 74, </key>
+<key name="scal"> 20,54, </key>
+<key name="scalar"> 17, </key>
+<key name="scen"> 54, </key>
+<key name="script"> 16,18,19,20,21,2,3,4,22,24,7,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55, </key>
+<key name="se"> 16,18,19,20,21,2,3,4,5,22,6,7,25,8,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,68,39,40,41,72,42,44,45,75,46,47,48,49,50,51,52,79,54,55, </key>
+<key name="seam"> 66, </key>
+<key name="search"> 32,62,74, </key>
+<key name="second"> 18,63,65,44, </key>
+<key name="secondnodeid1"> 76, </key>
+<key name="secondnodeid2"> 76, </key>
+<key name="secondnodeidonfreebord"> 76, </key>
+<key name="section"> 0,6,24,66,75, </key>
+<key name="seg"> 65, </key>
+<key name="segment"> 14,16,20,7,9,58,34,61,63,65,70,73,75,76,78, </key>
+<key name="select"> 14,0,18,1,20,5,22,23,24,7,25,8,26,27,10,28,29,31,12,13,32,36,62,63,65,38,66,67,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53,54, </key>
+<key name="selectabl"> 60, </key>
+<key name="selection"> 18,1,22,26,27,10,74,50, </key>
+<key name="sens"> 15, </key>
+<key name="separat"> 48, </key>
+<key name="sequenc"> 44, </key>
+<key name="set"> 15,16,18,20,22,6,24,26,9,29,13,34,61,63,65,35,66,67,71,74,44,46,77,50,54, </key>
+<key name="setmaxelementarea"> 7, </key>
+<key name="setnam"> 64,75, </key>
+<key name="setting"> 24, </key>
+<key name="seven"> 13,63, </key>
+<key name="sew"> 13,44,76, </key>
+<key name="sewbordertosid"> 76, </key>
+<key name="sewconformfreeborder"> 76, </key>
+<key name="sewfreeborder"> 76, </key>
+<key name="sewsideelement"> 76, </key>
+<key name="sg"> 58,63,70,76, </key>
+<key name="shad"> 0,67,77, </key>
+<key name="shall"> 22,28,29,36,62,66,72,42,47,49,50,51, </key>
+<key name="shap"> 14,15,16,13,63,66,68,69,71,46, </key>
+<key name="shape_mesh"> 63, </key>
+<key name="shape1d"> 63, </key>
+<key name="shapetyp"> 7,9,58,63,70,75,76, </key>
+<key name="shel"> 71, </key>
+<key name="shell"> 70,71, </key>
+<key name="shift"> 18,1,27,40,46, </key>
+<key name="shortest"> 55, </key>
+<key name="should"> 20,8,26,12,13,66,68,71,72,42,74,44,46,52, </key>
+<key name="show"> 20,6,13,74,54, </key>
+<key name="shown"> 17,46, </key>
+<key name="shrink"> 67, </key>
+<key name="sid"> 16,7,9,37,65,68,44,45,76, </key>
+<key name="simp"> 5,24,38, </key>
+<key name="simpl"> 15,18,13,66, </key>
+<key name="simplex"> 21,2, </key>
+<key name="sin"> 63, </key>
+<key name="sin_bot"> 63, </key>
+<key name="sin_top"> 63, </key>
+<key name="six"> 13,63, </key>
+<key name="siz"> 0,65,73,75,46, </key>
+<key name="sk"> 21,2, </key>
+<key name="sketch"> 9, </key>
+<key name="sketcher"> 9, </key>
+<key name="sketcher1"> 9, </key>
+<key name="sketcher2"> 9, </key>
+<key name="skew"> 17,27,61,70,45,50, </key>
+<key name="skew_margin"> 70, </key>
+<key name="slid"> 77, </key>
+<key name="small"> 54, </key>
+<key name="smesh"> 7,9,58,63,70,64,44,75,76,78, </key>
+<key name="smesh_mechanic"> 58,63,70,76, </key>
+<key name="smesh_mechanic_tetra"> 70, </key>
+<key name="smeshgroup1"> 58, </key>
+<key name="smooth"> 63,46, </key>
+<key name="smoothobject"> 63, </key>
+<key name="smp"> 66, </key>
+<key name="so"> 14,20,21,13,66,44,48, </key>
+<key name="solid"> 9,61,69, </key>
+<key name="somewhat"> 18, </key>
+<key name="soon"> 7, </key>
+<key name="sort"> 22,26,27,50, </key>
+<key name="sourc"> 69,74, </key>
+<key name="spac"> 15,66,71,42,49, </key>
+<key name="specifi"> 20,3,66,40,44,46, </key>
+<key name="specific"> 16,23,74, </key>
+<key name="specify"> 18,1,27,12,13,66,40,72,42,74,46,47,49,52, </key>
+<key name="spher"> 20,21,24, </key>
+<key name="split"> 16,20,2,6,65,44, </key>
+<key name="sqrt"> 63, </key>
+<key name="standalon"> 26,58,74, </key>
+<key name="standard"> 0,8,32,75,53, </key>
+<key name="start"> 14,20,6,9,13,61,43,44,49, </key>
+<key name="startendlength"> 9, </key>
+<key name="static"> 64, </key>
+<key name="step"> 12,72, </key>
+<key name="stor"> 66,74, </key>
+<key name="str"> 63,64, </key>
+<key name="straight"> 1,9,13,63,38, </key>
+<key name="stretch"> 54, </key>
+<key name="strict"> 54, </key>
+<key name="structur"> 24,25,63,64, </key>
+<key name="study"> 9,58,74,75, </key>
+<key name="stuf"> 54, </key>
+<key name="styl"> 7, </key>
+<key name="sub"> 7,9,13,32,36,66,42,44,47,49, </key>
+<key name="submenu"> 18,11,40,41, </key>
+<key name="submesh"> 14,22,23,7,25,26,27,12,13,39,72,46,49,50,53, </key>
+<key name="subshapeall"> 7,9,58,63,70,76, </key>
+<key name="subshapeallid"> 63,75, </key>
+<key name="subshapeallsort"> 63, </key>
+<key name="subshapelist"> 7,58, </key>
+<key name="subshapenam"> 7, </key>
+<key name="succed"> 9, </key>
+<key name="successful"> 73, </key>
<key name="sum"> 2, </key>
-<key name="supplement"> 37, </key>
-<key name="supplementary"> 26, </key>
-<key name="surfac"> 14,20,2,11,12,64,70,43, </key>
-<key name="surround"> 14,45, </key>
-<key name="swept"> 11,70, </key>
+<key name="supplement"> 38, </key>
+<key name="supplementary"> 27, </key>
+<key name="surfac"> 15,21,2,12,13,66,72,44, </key>
+<key name="surround"> 15,46, </key>
+<key name="swept"> 12,72, </key>
<key name="switch"> 1, </key>
-<key name="symmetrical"> 46,73, </key>
-<key name="symmetry"> 46,73, </key>
-<key name="syntax"> 71, </key>
-<key name="t"> 14,19,2,23,37,64,65,53, </key>
-<key name="t1"> 61, </key>
-<key name="tabl"> 1,19, </key>
-<key name="tak"> 20,49, </key>
-<key name="taken"> 13,22,25,8,64, </key>
-<key name="tap"> 16,25,60,68,47, </key>
-<key name="taper_margin"> 68, </key>
-<key name="target"> 67, </key>
-<key name="techniqu"> 45, </key>
-<key name="tetra"> 6,8,72,75, </key>
-<key name="tetrahedral"> 15,8,63,72, </key>
-<key name="tetrahedralization"> 23, </key>
-<key name="tetrahedrical"> 8, </key>
-<key name="tetrahedron"> 14,15,17,2,6,8,61,34,72,75, </key>
-<key name="tetran"> 8, </key>
-<key name="th"> 64,43, </key>
-<key name="them"> 13,17,1,19,2,25,9,10,11,12,35,63,39,70,43,45,53, </key>
-<key name="themesh"> 6, </key>
-<key name="third"> 12, </key>
-<key name="thos"> 26,49, </key>
-<key name="thre"> 14,1,20,61,63,37,43,46, </key>
-<key name="threshold"> 71, </key>
-<key name="tick"> 53, </key>
+<key name="symmetrical"> 47,76, </key>
+<key name="symmetry"> 47,76, </key>
+<key name="syntax"> 74, </key>
+<key name="t"> 15,20,2,24,38,66,67,73,54, </key>
+<key name="t1"> 63, </key>
+<key name="tabl"> 1,20, </key>
+<key name="tak"> 21,50, </key>
+<key name="taken"> 14,23,26,9,66, </key>
+<key name="tap"> 17,26,61,70,48, </key>
+<key name="taper_margin"> 70, </key>
+<key name="target"> 69, </key>
+<key name="techniqu"> 46, </key>
+<key name="test"> 63, </key>
+<key name="tetra"> 7,9,75,78, </key>
+<key name="tetrahedral"> 16,9,65,75, </key>
+<key name="tetrahedralization"> 24, </key>
+<key name="tetrahedrical"> 9, </key>
+<key name="tetrahedron"> 15,16,18,2,7,9,63,35,75,78, </key>
+<key name="tetran"> 9, </key>
+<key name="th"> 66,44, </key>
+<key name="them"> 14,18,1,20,2,26,10,11,12,13,36,65,40,72,44,46,54, </key>
+<key name="themesh"> 7, </key>
+<key name="third"> 13, </key>
+<key name="thos"> 27,50, </key>
+<key name="thre"> 15,1,21,63,65,38,44,47, </key>
+<key name="threshold"> 74, </key>
+<key name="tick"> 54, </key>
<key name="tim"> 0, </key>
-<key name="tmp"> 6, </key>
-<key name="togeth"> 33, </key>
-<key name="toggl"> 17,71,48, </key>
-<key name="toleranc"> 35,70,71,73, </key>
-<key name="tool"> 71,51, </key>
-<key name="toolbar"> 20,2,21,23,24,7,26,27,28,30,11,12,32,64,39,40,70,42,44,45,47,49,50,52,76,53,54, </key>
-<key name="top"> 61, </key>
-<key name="topological"> 14,43, </key>
-<key name="topology"> 14, </key>
-<key name="toru"> 7, </key>
-<key name="total"> 52, </key>
-<key name="toward"> 45, </key>
-<key name="transform"> 28,73, </key>
-<key name="transformation"> 35,41,43,46,48, </key>
-<key name="translat"> 73,48, </key>
-<key name="translation"> 73,48, </key>
-<key name="transparency"> 0,74, </key>
-<key name="transparent"> 74, </key>
-<key name="transtorm"> 7, </key>
-<key name="tria"> 6,8,73, </key>
-<key name="tria_mesh"> 8, </key>
-<key name="triangl"> 14,15,17,1,18,20,6,8,27,11,33,32,59,36,61,63,66,68,69,70,44,72,47,73,49,50,75,53, </key>
-<key name="triangular"> 15,33, </key>
-<key name="triangulation"> 8, </key>
-<key name="trihedron"> 53, </key>
-<key name="tritoquad"> 61, </key>
-<key name="truncat"> 72, </key>
-<key name="try"> 23,63, </key>
-<key name="tt"> 8,61, </key>
-<key name="tui"> 15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54, </key>
-<key name="tupl"> 62, </key>
-<key name="two"> 14,17,5,25,26,8,27,12,57,36,61,63,64,66,67,68,69,43,47,73,48,50,51,52, </key>
-<key name="typ"> 14,17,19,20,2,22,23,25,11,12,39,70,71,43,52, </key>
-<key name="typical"> 45, </key>
-<key name="u"> 14,43, </key>
-<key name="unary"> 71, </key>
-<key name="unassign"> 38, </key>
-<key name="uncheck"> 53, </key>
-<key name="uniform"> 45, </key>
-<key name="union"> 57,49,50,51, </key>
-<key name="uniongroup"> 57, </key>
-<key name="unionid"> 72, </key>
-<key name="unit"> 61,43,49,50,51, </key>
-<key name="unles"> 37, </key>
-<key name="unv"> 31, </key>
-<key name="up"> 19,9,29, </key>
-<key name="updat"> 0,6,42,45, </key>
-<key name="updateobjbrows"> 57,61,68,73, </key>
-<key name="upload"> 71, </key>
-<key name="us"> 14,15,19,3,5,23,24,25,11,12,33,35,61,63,64,66,70,71,43,45,74,51,53, </key>
-<key name="usag"> 16,6,61,72, </key>
-<key name="useful"> 0,17,25,12,63, </key>
-<key name="usual"> 43,45, </key>
-<key name="v"> 14, </key>
-<key name="valu"> 13,16,19,20,2,23,6,12,58,36,37,38,71,44,72, </key>
-<key name="vari"> 20, </key>
-<key name="variabl"> 62, </key>
+<key name="tmp"> 7, </key>
+<key name="togeth"> 34, </key>
+<key name="toggl"> 18,74,49, </key>
+<key name="toleranc"> 5,36,72,74,76, </key>
+<key name="tool"> 74,52, </key>
+<key name="toolbar"> 21,2,5,22,24,25,8,27,28,29,31,12,13,33,62,66,40,41,72,43,45,46,48,50,51,53,79,54,55, </key>
+<key name="top"> 63,73, </key>
+<key name="topological"> 15,44, </key>
+<key name="topology"> 15, </key>
+<key name="toru"> 8, </key>
+<key name="total"> 53, </key>
+<key name="toward"> 46, </key>
+<key name="transform"> 29,76, </key>
+<key name="transformation"> 36,42,44,47,49, </key>
+<key name="translat"> 76,49, </key>
+<key name="translation"> 76,49, </key>
+<key name="transparency"> 0,77, </key>
+<key name="transparent"> 77, </key>
+<key name="transtorm"> 8, </key>
+<key name="tria"> 7,9,76, </key>
+<key name="tria_mesh"> 9, </key>
+<key name="triangl"> 15,16,18,1,19,21,7,9,28,12,34,33,60,37,63,65,68,70,71,72,45,75,48,76,50,51,78,54, </key>
+<key name="triangular"> 16,34, </key>
+<key name="triangulation"> 9, </key>
+<key name="trihedron"> 54, </key>
+<key name="tritoquad"> 63, </key>
+<key name="tru"> 63, </key>
+<key name="truncat"> 75, </key>
+<key name="try"> 24,65, </key>
+<key name="tt"> 9,63, </key>
+<key name="tui"> 16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55, </key>
+<key name="tupl"> 64, </key>
+<key name="two"> 15,18,6,26,27,9,28,13,58,37,63,65,66,68,69,70,71,44,48,76,49,51,52,53, </key>
+<key name="typ"> 15,18,20,21,2,23,24,26,12,13,40,72,74,44,53, </key>
+<key name="typical"> 46, </key>
+<key name="u"> 15,44, </key>
+<key name="unary"> 74, </key>
+<key name="unassign"> 39, </key>
+<key name="uncheck"> 54, </key>
+<key name="uniform"> 46, </key>
+<key name="union"> 58,50,51,52, </key>
+<key name="uniongroup"> 58, </key>
+<key name="unionid"> 75, </key>
+<key name="unit"> 5,63,44,50,51,52, </key>
+<key name="unles"> 38, </key>
+<key name="unv"> 32, </key>
+<key name="up"> 20,10,30, </key>
+<key name="updat"> 0,7,43,46, </key>
+<key name="updateobjbrows"> 58,63,70,76, </key>
+<key name="upload"> 74, </key>
+<key name="us"> 15,16,20,3,6,24,25,26,12,13,34,36,63,65,66,68,72,74,44,46,77,52,54, </key>
+<key name="usag"> 17,7,63,75, </key>
+<key name="useful"> 0,18,26,13,65, </key>
+<key name="usual"> 44,46, </key>
+<key name="v"> 15, </key>
+<key name="valu"> 14,17,20,21,2,24,7,13,59,37,38,39,74,45,75, </key>
+<key name="vari"> 21, </key>
+<key name="variabl"> 64, </key>
<key name="variou"> 0, </key>
-<key name="ve"> 17, </key>
-<key name="vector"> 11,12,61,70,41,46,73,48,54, </key>
-<key name="versa"> 7, </key>
-<key name="vert"> 61, </key>
-<key name="vertex"> 14,64,67, </key>
-<key name="vertex_"> 61, </key>
-<key name="vertic"> 61,64,66,67, </key>
-<key name="very"> 17,12,63, </key>
-<key name="via"> 71,52,53, </key>
-<key name="vic"> 7, </key>
-<key name="vid"> 61, </key>
-<key name="view"> 0,17,1,18,20,2,21,5,25,26,9,27,28,29,11,12,32,36,39,40,70,71,43,44,45,47,49,50,52,75,76,53,54, </key>
-<key name="visibl"> 53, </key>
-<key name="visual"> 16, </key>
-<key name="visualiz"> 53, </key>
+<key name="ve"> 18, </key>
+<key name="vector"> 12,13,63,72,42,47,76,49,55, </key>
+<key name="versa"> 8, </key>
+<key name="vert"> 63, </key>
+<key name="vertex"> 15,63,66,69,73, </key>
+<key name="vertex_"> 63, </key>
+<key name="vertic"> 63,66,68,69, </key>
+<key name="very"> 18,13,65, </key>
+<key name="via"> 74,53,54, </key>
+<key name="vic"> 8, </key>
+<key name="vid"> 63, </key>
+<key name="view"> 0,18,1,19,21,2,22,6,26,27,10,28,29,30,12,13,33,37,40,41,72,74,44,45,46,48,50,51,53,78,79,54,55, </key>
+<key name="visibl"> 54, </key>
+<key name="visual"> 17, </key>
+<key name="visualiz"> 54, </key>
<key name="vk"> 2, </key>
-<key name="volum"> 13,14,15,16,17,2,22,6,25,8,10,12,60,61,34,68,71,73,52,75,76, </key>
-<key name="volume_margin"> 68, </key>
-<key name="vtk"> 0,53, </key>
-<key name="vxy"> 8,73, </key>
-<key name="wa_margin"> 68, </key>
-<key name="walk"> 64, </key>
-<key name="warp"> 16,26,60,68,49,54, </key>
-<key name="way"> 14,17,23,24,25,12,64,38,51, </key>
-<key name="weight"> 45, </key>
-<key name="well"> 64, </key>
-<key name="wheth"> 71, </key>
-<key name="whil"> 66,39, </key>
-<key name="whit"> 12,55, </key>
-<key name="whol"> 2,11,12,70,71,45,48, </key>
-<key name="whos"> 21,25,26,37,49, </key>
-<key name="will"> 13,14,0,17,1,18,19,20,2,21,22,23,6,24,7,25,26,9,28,29,30,11,12,31,33,32,59,36,61,63,34,37,64,67,39,40,70,42,71,43,44,45,47,74,49,51,52,76,54, </key>
-<key name="window"> 5, </key>
-<key name="wir"> 15,8,12,33,61,63,73, </key>
-<key name="wire_polylin"> 61, </key>
-<key name="wire_polyline_edg"> 61, </key>
-<key name="wire_polyline_mesh"> 61, </key>
-<key name="wirefram"> 0,65, </key>
-<key name="wish"> 23,7,9,31,53, </key>
-<key name="within"> 19,64,43, </key>
-<key name="without"> 1,12,68,69, </key>
-<key name="word"> 19, </key>
-<key name="work"> 1,12,63,67, </key>
-<key name="worst"> 20, </key>
-<key name="would"> 17,69,43, </key>
-<key name="ww"> 8, </key>
-<key name="x"> 14,5,54, </key>
-<key name="x0"> 61, </key>
-<key name="y"> 14,5, </key>
-<key name="y0"> 61, </key>
-<key name="your"> 13,14,16,0,17,1,18,19,20,2,21,5,22,23,24,25,28,29,30,31,33,32,35,36,34,64,65,38,39,40,41,71,44,45,46,47,48,52,76,54, </key>
-<key name="z"> 14,5, </key>
-<key name="z0"> 61, </key>
-<key name="zero"> 64, </key>
-<key name="zoom"> 53, </key>
+<key name="volum"> 14,15,16,17,18,2,23,7,26,9,11,13,61,63,35,70,74,76,53,78,79, </key>
+<key name="volume_margin"> 70, </key>
+<key name="vtk"> 0,54, </key>
+<key name="vxy"> 9,76, </key>
+<key name="wa_margin"> 70, </key>
+<key name="walk"> 66, </key>
+<key name="warp"> 17,27,61,70,50,55, </key>
+<key name="way"> 15,18,24,25,26,13,66,39,52, </key>
+<key name="weight"> 46, </key>
+<key name="well"> 66, </key>
+<key name="wheth"> 74, </key>
+<key name="whil"> 5,68,40, </key>
+<key name="whit"> 13,56, </key>
+<key name="whol"> 16,2,12,13,72,74,46,49, </key>
+<key name="whos"> 22,26,27,38,50, </key>
+<key name="will"> 14,15,0,18,1,19,20,21,2,5,22,23,24,7,25,8,26,27,10,29,30,31,12,13,32,34,33,60,37,63,65,35,38,66,69,40,41,72,43,74,44,45,46,48,77,50,52,53,79,55, </key>
+<key name="window"> 6, </key>
+<key name="wir"> 16,9,13,34,63,65,76, </key>
+<key name="wire_polylin"> 63, </key>
+<key name="wire_polyline_edg"> 63, </key>
+<key name="wire_polyline_mesh"> 63, </key>
+<key name="wirefram"> 0,67, </key>
+<key name="wish"> 24,8,10,32,54, </key>
+<key name="within"> 20,66,44, </key>
+<key name="without"> 1,13,70,71, </key>
+<key name="word"> 20, </key>
+<key name="work"> 1,13,65,69, </key>
+<key name="worst"> 21, </key>
+<key name="would"> 18,71,44, </key>
+<key name="wrong"> 63, </key>
+<key name="ww"> 9, </key>
+<key name="x"> 15,6,63,55, </key>
+<key name="x0"> 63, </key>
+<key name="xyz"> 63, </key>
+<key name="y"> 15,6,63, </key>
+<key name="y0"> 63, </key>
+<key name="your"> 14,15,17,0,18,1,19,20,21,2,22,6,23,24,25,26,29,30,31,32,34,33,36,37,35,66,67,39,40,41,42,74,45,46,47,48,49,53,79,55, </key>
+<key name="z"> 15,6,63, </key>
+<key name="z0"> 63, </key>
+<key name="zero"> 66, </key>
+<key name="zoom"> 54, </key>
</ftswdata>
<item name="Basic meshing algorithms" url="files/about_meshing_algorithms.htm" />
<item name="Projection Algorithms" url="projection_algorithms.htm" />
<item name="Radial Prism Algorithm" url="radial_prism.htm" />
+ <item name="Segments around Vertex Algorithm" url="segments_around_vertex_algorithm.htm" />
<item name="Prism 3D Algorithm" url="prism_3d_algorithm.htm" />
</book>
<book name="Defining hypotheses" >
<item name="Additional Hypotheses" url="files/non_conform_mesh_allowed_hypothesis.htm" />
</book>
<item name="Constructing submeshes" url="files/constructing_submeshes.htm" />
+ <item name="Building Compounds" url="building_compounds.htm" />
<item name="Editing Meshes" url="files/reassigning_hypotheses_and_algorithms.htm" />
</book>
<book name="Viewing meshes" >
<item name="Viewing meshes" url="about_viewing_meshes.htm" />
- <item name="VTK 3D Viewer" url="files/vtk_3d_viewer.htm" />
<item name="Mesh infos" url="files/viewing_mesh_info.htm" />
<item name="Numbering" url="files/displaying_nodes_numbers.htm" />
<item name="Display Mode" url="presentation.htm" />
<item name="Merging Elements" url="merge_elements.htm" />
</book>
<item name="Moving nodes" url="files/displacing_nodes.htm" />
+ <item name="Mesh through point" url="mesh_through_point.htm" />
<item name="Diagonal inversion of elements" url="files/diagonal_iversion_of_elements.htm" />
<item name="Uniting two triangles" url="files/uniting_two_triangles.htm" />
<item name="Uniting a set of triangles" url="files/uniting_a_set_of_triangles.htm" />
<item name="Pattern mapping" url="pattern_mapping.htm" />
<item name="Convert to/from Quadratic Mesh" url="convert_to_from_quadratic_mesh.htm" />
</book>
- <item name="Python Interface smesh.py" url="smeshpy_doc/namespacesmesh.html" />
- <book name="TUI Scripts" >
+ <item name="Python Interface smesh.py" url="smeshpy_doc/namespacesmesh.html" />
+ <book name="TUI Scripts" >
<item name="Creating Meshes" url="constructing_meshes.htm" />
<item name="Viewing Meshes" url="viewing_meshes.htm" />
<item name="Defining Hypotheses" url="defining_hypotheses_tui.htm" />
SMESH_BasicHypothesis.idl \
SMESH_Filter.idl \
SMESH_Group.idl \
- SMESH_Pattern.idl
+ SMESH_Pattern.idl \
+ SMESH_MeshEditor.idl
EXTRA_DIST+= $(BASEIDL_FILES)
SMESH_BasicHypothesisSK.cc \
SMESH_FilterSK.cc \
SMESH_GroupSK.cc \
- SMESH_PatternSK.cc
+ SMESH_PatternSK.cc \
+ SMESH_MeshEditorSK.cc
# header files must be exported: other modules have to use this library
nodist_salomeinclude_HEADERS= $(BASEIDL_FILES:%.idl=%.hh)
raises (SALOME::SALOME_Exception);
};
+ /*!
+ * interface of "SegmentLengthAroundVertex" hypothesis.
+ * This hypothesis specifies length of segments adjacent to the vertex the
+ * hypothesis is assigned to
+ */
+ interface StdMeshers_SegmentLengthAroundVertex : SMESH::SMESH_Hypothesis
+ {
+ /*!
+ * Sets <length> parameter value
+ */
+ void SetLength(in double length)
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <length> parameter value
+ */
+ double GetLength();
+ };
+
+ /*!
+ * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm
+ */
+ interface StdMeshers_SegmentAroundVertex_0D : SMESH::SMESH_0D_Algo
+ {
+ };
+
/*!
* StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm
*/
{
};
+ /*!
+ * StdMeshers_CompositeSegment_1D: interface of "Composite side discretisation" algorithm
+ */
+ interface StdMeshers_CompositeSegment_1D : SMESH::SMESH_1D_Algo
+ {
+ };
+
/*!
* StdMeshers_MEFISTO_2D: interface of "Triangle (Mefisto)" algorithm
*/
};
/*!
- * StdMeshers_Prism_3D: interface of "Prism 3D" algorithm
+ * StdMeshers_Prism_3D: interface of "3D extrusion" algorithm
*/
interface StdMeshers_Prism_3D : SMESH::SMESH_3D_Algo
{
FT_BelongToGeom,
FT_BelongToPlane,
FT_BelongToCylinder,
+ FT_BelongToGenSurface,
FT_LyingOnGeom,
FT_RangeOfIds,
FT_BadOrientedVolume,
/*!
* Logical functor (predicate) "Belong To Surface".
- * Base interface for "belong to plane" and "belong to cylinder interfaces"
+ * Base interface for "belong to plane" and "belong to cylinder"
+ * and "Belong To Generic Surface" interfaces
*/
interface BelongToSurface: Predicate
{
- void SetTolerance( in double theToler );
- double GetTolerance();
- void SetShapeName( in string theName, in ElementType theType );
- void SetShape( in string theID, in string theName, in ElementType theType );
- string GetShapeName();
- string GetShapeID();
+ void SetTolerance( in double theToler );
+ double GetTolerance();
+ void SetShapeName( in string theName, in ElementType theType );
+ void SetShape( in string theID, in string theName, in ElementType theType );
+ string GetShapeName();
+ string GetShapeID();
+ /*!
+ * Limit surface extent to bounding box of boundaries (edges)
+ * in surface parametric space. Boundaries are ignored by default
+ */
+ void SetUseBoundaries( in boolean theUseBndRestrictions );
+ boolean GetUseBoundaries();
};
-
/*!
* Logical functor (predicate) "Belong To Plane".
- * Verify whether mesh element lie in pointed Geom planar object
+ * Verify whether mesh element lie on pointed Geom planar object
*/
interface BelongToPlane: BelongToSurface
{
};
/*!
- * Logical functor (predicate) "Belong To Culinder".
- * Verify whether mesh element lie in pointed Geom cylindrical object
+ * Logical functor (predicate) "Belong To Cylinder".
+ * Verify whether mesh element lie on pointed Geom cylindrical object
*/
interface BelongToCylinder: BelongToSurface
{
void SetCylinder( in GEOM::GEOM_Object theGeom, in ElementType theType );
};
+ /*!
+ * Logical functor (predicate) "Belong To Generic Surface".
+ * Verify whether mesh element lie in pointed Geom cylindrical object
+ */
+ interface BelongToGenSurface: BelongToSurface
+ {
+ void SetSurface( in GEOM::GEOM_Object theGeom, in ElementType theType );
+ };
+
/*!
* Logical functor (predicate) "Lying On Geometry".
* Verify whether mesh element or node lying or partially lying on the pointed Geom Object
BelongToGeom CreateBelongToGeom();
BelongToPlane CreateBelongToPlane();
BelongToCylinder CreateBelongToCylinder();
+ BelongToGenSurface CreateBelongToGenSurface();
LyingOnGeom CreateLyingOnGeom();
module SMESH
{
typedef sequence<GEOM::GEOM_Object> object_array;
- typedef sequence<SMESH_Mesh> mesh_array;
+ typedef sequence<SMESH_Mesh> mesh_array;
interface FilterManager;
interface SMESH_Pattern;
- enum AlgoStateErrorName { MISSING_ALGO, MISSING_HYPO, NOT_CONFORM_MESH, BAD_PARAM_VALUE };
- struct AlgoStateError {
- AlgoStateErrorName name;
+ /*!
+ * Hypothesis definintion error
+ */
+ struct AlgoStateError
+ {
+ Hypothesis_Status state;
string algoName;
long algoDim;
boolean isGlobalAlgo;
};
typedef sequence<AlgoStateError> algo_error_array;
-
+
+ /*!
+ * Mesh computation error
+ */
+ enum ComputeErrorName
+ {
+ COMPERR_OK ,
+ COMPERR_BAD_INPUT_MESH, // wrong mesh on lower submesh
+ COMPERR_STD_EXCEPTION , // some std exception raised
+ COMPERR_OCC_EXCEPTION , // OCC exception raised
+ COMPERR_SLM_EXCEPTION , // SALOME exception raised
+ COMPERR_EXCEPTION , // other exception raised
+ COMPERR_MEMORY_PB , // memory allocation problem
+ COMPERR_ALGO_FAILED , // computation failed
+ COMPERR_BAD_SHAPE // bad geometry
+ };
+ struct ComputeError
+ {
+ short code; // ComputeErrorName or, if negative, algo specific code
+ string comment; // textual problem description
+ string algoName;
+ short subShapeID; // id of subshape of a shape to mesh
+ };
+ typedef sequence<ComputeError> compute_error_array;
+
+
interface SMESH_Gen : Engines::Component, SALOMEDS::Driver
{
in GEOM::GEOM_Object theSubObject )
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Return errors of mesh computation
+ * compute_error_array is empty if everything is OK
+ */
+ compute_error_array GetComputeErrors( in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Object theSubObject )
+ raises ( SALOME::SALOME_Exception );
+
/*!
* Return indeces of faces, edges and vertices of given subshapes
* within theMainObject
in long theElementID)
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Concatenate the given meshes into one mesh.
+ * Union groups with the same name and type if
+ * theUniteIdenticalGroups flag is true.
+ * Merge coincident nodes and elements if
+ * theMergeNodesAndElements flag is true.
+ */
+ SMESH_Mesh Concatenate(in mesh_array theMeshesArray,
+ in boolean theUniteIdenticalGroups,
+ in boolean theMergeNodesAndElements,
+ in double theMergeTolerance)
+ raises ( SALOME::SALOME_Exception );
+
};
};
{
enum Dimension
{
+ DIM_0D,
DIM_1D,
DIM_2D,
DIM_3D
};
+ interface SMESH_0D_Algo : SMESH_Algo
+ {
+ /*!
+ *
+ */
+ };
+
interface SMESH_1D_Algo : SMESH_Algo
{
/*!
interface SMESH_GroupBase;
typedef sequence<SMESH_GroupBase> ListOfGroups;
- typedef sequence<double> double_array ;
- typedef sequence<long> long_array ;
- typedef sequence<string> string_array ;
+ typedef sequence<double > double_array ;
+ typedef sequence<long > long_array ;
+ typedef sequence<string > string_array ;
typedef sequence<long_array> array_of_long_array ;
enum log_command
struct PointStruct { double x;
double y;
double z; } ;
+
+ typedef sequence<PointStruct> nodes_array;
+
struct DirStruct { PointStruct PS ; } ; // analog to Occ Direction
struct AxisStruct { double x;
HYP_MISSING, // algo misses a hypothesis
HYP_CONCURENT, // several applicable hypotheses
HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
+ HYP_HIDDEN_ALGO, // an algo is hidden by an upper dim algo generating all-dim elements
+ HYP_HIDING_ALGO, // an algo hides lower dim algos by generating all-dim elements
HYP_UNKNOWN_FATAL,// --- all statuses below should be considered as fatal
// for Add/RemoveHypothesis operations
HYP_INCOMPATIBLE, // hypothesis does not fit algo
interface SMESH_MeshEditor;
interface SMESH_Mesh : SALOME::GenericObj, SMESH_IDSource
{
- ///*!
- // * Associate a Shape to a Mesh created with NewEmpty
- // */
- //boolean SetMesh(in GEOM::GEOM_Object anObject)
- // raises (SALOME::SALOME_Exception);
+ /*!
+ * Return true if there is a geometry to be meshed
+ */
+ boolean HasShapeToMesh()
+ raises (SALOME::SALOME_Exception);
/*!
- * Get the subMesh object associated to a subShape. The subMesh object
- * gives access to nodes and elements IDs.
- * SubMesh will be used instead of SubShape in a next idl version to
- * adress a specific subMesh...
+ * Get geom shape to mesh. A result sould not be nil. Use HasShapeToMesh()
+ * to know if a returned shape
*/
- SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name)
+ GEOM::GEOM_Object GetShapeToMesh()
raises (SALOME::SALOME_Exception);
- ///*!
- // * Create a subMesh without reference to a subShape
- // */
- //SMESH_subMesh NewEmpty()
- // raises (SALOME::SALOME_Exception);
/*!
- * Get geom shape to mesh. A result may be nil
+ * Get the subMesh object associated to a subShape. The subMesh object
+ * gives access to nodes and elements IDs.
+ * SubMesh will be used instead of SubShape in a next idl version to
+ * adress a specific subMesh...
*/
- GEOM::GEOM_Object GetShapeToMesh()
+ SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name)
raises (SALOME::SALOME_Exception);
/*!
void RemoveSubMesh(in SMESH_subMesh aSubMesh)
raises (SALOME::SALOME_Exception);
+
/*!
* Create a group
*/
SMESH_MeshEditor GetMeshEditor()
raises (SALOME::SALOME_Exception);
+ /*!
+ * Return SMESH_MeshEditor that would not modify the mesh but
+ * fill MeshPreviewStruct
+ */
+ SMESH_MeshEditor GetMeshEditPreviewer()
+ raises (SALOME::SALOME_Exception);
+
/*! Check group names for duplications.
* Consider maximum group name length stored in MED file.
*/
/*!
* Get mesh pointer
*/
- long GetMeshPtr();
+ long long GetMeshPtr();
/*!
* Get XYZ coordinates of node as list of double
raises (SALOME::SALOME_Exception);
};
- /*!
- * This interface makes modifications on the Mesh - removing elements and nodes etc.
- */
- interface NumericalFunctor;
- interface SMESH_MeshEditor
- {
- boolean RemoveElements(in long_array IDsOfElements);
-
- boolean RemoveNodes(in long_array IDsOfNodes);
-
- long AddNode(in double x, in double y, in double z);
-
- /*!
- * Create edge, either linear and quadratic (this is determed
- * by number of given nodes).
- * \param IdsOfNodes List of node IDs for creation of element.
- * Needed order of nodes in this list corresponds to description
- * of MED. This description is located by the following link:
- * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
- */
- long AddEdge(in long_array IDsOfNodes);
-
- /*!
- * Create face, either linear and quadratic (this is determed
- * by number of given nodes).
- * \param IdsOfNodes List of node IDs for creation of element.
- * Needed order of nodes in this list corresponds to description
- * of MED. This description is located by the following link:
- * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
- */
- long AddFace(in long_array IDsOfNodes);
-
- long AddPolygonalFace(in long_array IdsOfNodes);
-
- /*!
- * Create volume, either linear and quadratic (this is determed
- * by number of given nodes).
- * \param IdsOfNodes List of node IDs for creation of element.
- * Needed order of nodes in this list corresponds to description
- * of MED. This description is located by the following link:
- * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
- */
- long AddVolume(in long_array IDsOfNodes);
-
- /*!
- * Create volume of many faces, giving nodes for each face.
- * \param IdsOfNodes List of node IDs for volume creation face by face.
- * \param Quantities List of integer values, Quantities[i]
- * gives quantity of nodes in face number i.
- */
- long AddPolyhedralVolume (in long_array IdsOfNodes,
- in long_array Quantities);
-
- /*!
- * Create volume of many faces, giving IDs of existing faces.
- * \param IdsOfFaces List of face IDs for volume creation.
- * \note The created volume will refer only to nodes
- * of the given faces, not to the faces itself.
- */
- long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
-
- boolean MoveNode(in long NodeID, in double x, in double y, in double z);
-
- boolean InverseDiag(in long NodeID1, in long NodeID2);
-
- boolean DeleteDiag(in long NodeID1, in long NodeID2);
-
- boolean Reorient(in long_array IDsOfElements);
-
- boolean ReorientObject(in SMESH_IDSource theObject);
-
- /*!
- * \brief Fuse neighbour triangles into quadrangles.
- * \param theElems The triangles to be fused.
- * \param theCriterion Is used to choose a neighbour to fuse with.
- * \param theMaxAngle Is a max angle between element normals at which fusion
- * is still performed; theMaxAngle is mesured in radians.
- * \return TRUE in case of success, FALSE otherwise.
- */
- boolean TriToQuad (in long_array IDsOfElements,
- in NumericalFunctor Criterion,
- in double MaxAngle);
-
- /*!
- * \brief Fuse neighbour triangles into quadrangles.
- *
- * Behaves like the above method, taking list of elements from \a theObject
- */
- boolean TriToQuadObject (in SMESH_IDSource theObject,
- in NumericalFunctor Criterion,
- in double MaxAngle);
-
- /*!
- * \brief Split quadrangles into triangles.
- * \param theElems The faces to be splitted.
- * \param theCriterion Is used to choose a diagonal for splitting.
- * \return TRUE in case of success, FALSE otherwise.
- */
- boolean QuadToTri (in long_array IDsOfElements,
- in NumericalFunctor Criterion);
-
- /*!
- * \brief Split quadrangles into triangles.
- *
- * Behaves like the above method, taking list of elements from \a theObject
- */
- boolean QuadToTriObject (in SMESH_IDSource theObject,
- in NumericalFunctor Criterion);
-
- /*!
- * \brief Split quadrangles into triangles.
- * \param theElems The faces to be splitted.
- * \param the13Diag Is used to choose a diagonal for splitting.
- * \return TRUE in case of success, FALSE otherwise.
- */
- boolean SplitQuad (in long_array IDsOfElements,
- in boolean Diag13);
-
- /*!
- * \brief Split quadrangles into triangles.
- *
- * Behaves like the above method, taking list of elements from \a theObject
- */
- boolean SplitQuadObject (in SMESH_IDSource theObject,
- in boolean Diag13);
-
- /*!
- * Find better splitting of the given quadrangle.
- * \param IDOfQuad ID of the quadrangle to be splitted.
- * \param Criterion A criterion to choose a diagonal for splitting.
- * \return 1 if 1-3 diagonal is better, 2 if 2-4
- * diagonal is better, 0 if error occurs.
- */
- long BestSplit (in long IDOfQuad,
- in NumericalFunctor Criterion);
-
- enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
-
- boolean Smooth(in long_array IDsOfElements,
- in long_array IDsOfFixedNodes,
- in long MaxNbOfIterations,
- in double MaxAspectRatio,
- in Smooth_Method Method);
-
- boolean SmoothObject(in SMESH_IDSource theObject,
- in long_array IDsOfFixedNodes,
- in long MaxNbOfIterations,
- in double MaxAspectRatio,
- in Smooth_Method Method);
-
- boolean SmoothParametric(in long_array IDsOfElements,
- in long_array IDsOfFixedNodes,
- in long MaxNbOfIterations,
- in double MaxAspectRatio,
- in Smooth_Method Method);
-
- boolean SmoothParametricObject(in SMESH_IDSource theObject,
- in long_array IDsOfFixedNodes,
- in long MaxNbOfIterations,
- in double MaxAspectRatio,
- in Smooth_Method Method);
-
- void ConvertToQuadratic(in boolean theForce3d);
-
- boolean ConvertFromQuadratic();
-
- void RenumberNodes();
-
- void RenumberElements();
-
- void RotationSweep(in long_array IDsOfElements,
- in AxisStruct Axix,
- in double AngleInRadians,
- in long NbOfSteps,
- in double Tolerance);
-
- void RotationSweepObject(in SMESH_IDSource theObject,
- in AxisStruct Axix,
- in double AngleInRadians,
- in long NbOfSteps,
- in double Tolerance);
-
- void ExtrusionSweep(in long_array IDsOfElements,
- in DirStruct StepVector,
- in long NbOfSteps);
-
- /*!
- * Generate new elements by extrusion of theElements
- * by StepVector by NbOfSteps
- * param ExtrFlags set flags for performing extrusion
- * param SewTolerance - uses for comparing locations of nodes if flag
- * EXTRUSION_FLAG_SEW is set
- */
- void AdvancedExtrusion(in long_array IDsOfElements,
- in DirStruct StepVector,
- in long NbOfSteps,
- in long ExtrFlags,
- in double SewTolerance);
-
- void ExtrusionSweepObject(in SMESH_IDSource theObject,
- in DirStruct StepVector,
- in long NbOfSteps);
-
- void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
- in DirStruct StepVector,
- in long NbOfSteps);
-
- void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
- in DirStruct StepVector,
- in long NbOfSteps);
-
- enum Extrusion_Error {
- EXTR_OK,
- EXTR_NO_ELEMENTS,
- EXTR_PATH_NOT_EDGE,
- EXTR_BAD_PATH_SHAPE,
- EXTR_BAD_STARTING_NODE,
- EXTR_BAD_ANGLES_NUMBER,
- EXTR_CANT_GET_TANGENT
- };
-
- Extrusion_Error ExtrusionAlongPath(in long_array IDsOfElements,
- in SMESH_Mesh PathMesh,
- in GEOM::GEOM_Object PathShape,
- in long NodeStart,
- in boolean HasAngles,
- in double_array Angles,
- in boolean HasRefPoint,
- in PointStruct RefPoint);
-
- Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource theObject,
- in SMESH_Mesh PathMesh,
- in GEOM::GEOM_Object PathShape,
- in long NodeStart,
- in boolean HasAngles,
- in double_array Angles,
- in boolean HasRefPoint,
- in PointStruct RefPoint);
-
- enum MirrorType { POINT, AXIS, PLANE };
-
- void Mirror (in long_array IDsOfElements,
- in AxisStruct Mirror,
- in MirrorType theMirrorType,
- in boolean Copy);
-
- void MirrorObject (in SMESH_IDSource theObject,
- in AxisStruct Mirror,
- in MirrorType theMirrorType,
- in boolean Copy);
-
- void Translate (in long_array IDsOfElements,
- in DirStruct Vector,
- in boolean Copy);
-
- void TranslateObject (in SMESH_IDSource theObject,
- in DirStruct Vector,
- in boolean Copy);
-
- void Rotate (in long_array IDsOfElements,
- in AxisStruct Axis,
- in double AngleInRadians,
- in boolean Copy);
-
- void RotateObject (in SMESH_IDSource theObject,
- in AxisStruct Axis,
- in double AngleInRadians,
- in boolean Copy);
-
- void FindCoincidentNodes (in double Tolerance,
- out array_of_long_array GroupsOfNodes);
-
- void MergeNodes (in array_of_long_array GroupsOfNodes);
-
- void MergeEqualElements();
-
- enum Sew_Error {
- SEW_OK,
- SEW_BORDER1_NOT_FOUND,
- SEW_BORDER2_NOT_FOUND,
- SEW_BOTH_BORDERS_NOT_FOUND,
- SEW_BAD_SIDE_NODES,
- SEW_VOLUMES_TO_SPLIT,
- // for SewSideElements() only:
- SEW_DIFF_NB_OF_ELEMENTS,
- SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
- SEW_BAD_SIDE1_NODES,
- SEW_BAD_SIDE2_NODES
- };
-
- Sew_Error SewFreeBorders (in long FirstNodeID1,
- in long SecondNodeID1,
- in long LastNodeID1,
- in long FirstNodeID2,
- in long SecondNodeID2,
- in long LastNodeID2,
- in boolean CreatePolygons,
- in boolean CreatePolyedrs);
-
- Sew_Error SewConformFreeBorders (in long FirstNodeID1,
- in long SecondNodeID1,
- in long LastNodeID1,
- in long FirstNodeID2,
- in long SecondNodeID2);
-
- Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
- in long SecondNodeIDOnFreeBorder,
- in long LastNodeIDOnFreeBorder,
- in long FirstNodeIDOnSide,
- in long LastNodeIDOnSide,
- in boolean CreatePolygons,
- in boolean CreatePolyedrs);
-
- Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
- in long_array IDsOfSide2Elements,
- in long NodeID1OfSide1ToMerge,
- in long NodeID1OfSide2ToMerge,
- in long NodeID2OfSide1ToMerge,
- in long NodeID2OfSide2ToMerge);
-
- /*!
- * Set new nodes for given element.
- * If number of nodes is not corresponded to type of
- * element - returns false
- */
- boolean ChangeElemNodes(in long ide, in long_array newIDs);
-
- /*!
- * If during last operation of MeshEditor some nodes were
- * created this method returns list of it's IDs, if new nodes
- * not creared - returns empty list
- */
- long_array GetLastCreatedNodes();
-
- /*!
- * If during last operation of MeshEditor some elements were
- * created this method returns list of it's IDs, if new elements
- * not creared - returns empty list
- */
- long_array GetLastCreatedElems();
-
- };
};
#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_MeshEditor.idl
+// $Header$
+
+#ifndef _SMESH_MESHEDITOR_IDL_
+#define _SMESH_MESHEDITOR_IDL_
+
+#include "SMESH_Mesh.idl"
+
+module SMESH
+{
+ /*!
+ * Structure used in mesh edit preview data
+ */
+ struct ElementSubType { ElementType SMDS_ElementType;
+ boolean isPoly;
+ long nbNodesInElement; };
+
+ typedef sequence<ElementSubType> types_array;
+
+ /*!
+ * Structure containing mesh edit preview data
+ */
+ struct MeshPreviewStruct { nodes_array nodesXYZ;
+ long_array elementConnectivities;
+ types_array elementTypes; };
+
+ /*!
+ * This interface makes modifications on the Mesh - removing elements and nodes etc.
+ */
+ interface NumericalFunctor;
+ interface SMESH_MeshEditor
+ {
+ boolean RemoveElements(in long_array IDsOfElements);
+
+ boolean RemoveNodes(in long_array IDsOfNodes);
+
+ long AddNode(in double x, in double y, in double z);
+
+ /*!
+ * Create edge, either linear and quadratic (this is determed
+ * by number of given nodes).
+ * \param IdsOfNodes List of node IDs for creation of element.
+ * Needed order of nodes in this list corresponds to description
+ * of MED. This description is located by the following link:
+ * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+ */
+ long AddEdge(in long_array IDsOfNodes);
+
+ /*!
+ * Create face, either linear and quadratic (this is determed
+ * by number of given nodes).
+ * \param IdsOfNodes List of node IDs for creation of element.
+ * Needed order of nodes in this list corresponds to description
+ * of MED. This description is located by the following link:
+ * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+ */
+ long AddFace(in long_array IDsOfNodes);
+
+ long AddPolygonalFace(in long_array IdsOfNodes);
+
+ /*!
+ * Create volume, either linear and quadratic (this is determed
+ * by number of given nodes).
+ * \param IdsOfNodes List of node IDs for creation of element.
+ * Needed order of nodes in this list corresponds to description
+ * of MED. This description is located by the following link:
+ * http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+ */
+ long AddVolume(in long_array IDsOfNodes);
+
+ /*!
+ * Create volume of many faces, giving nodes for each face.
+ * \param IdsOfNodes List of node IDs for volume creation face by face.
+ * \param Quantities List of integer values, Quantities[i]
+ * gives quantity of nodes in face number i.
+ */
+ long AddPolyhedralVolume (in long_array IdsOfNodes,
+ in long_array Quantities);
+
+ /*!
+ * Create volume of many faces, giving IDs of existing faces.
+ * \param IdsOfFaces List of face IDs for volume creation.
+ * \note The created volume will refer only to nodes
+ * of the given faces, not to the faces itself.
+ */
+ long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
+
+ boolean MoveNode(in long NodeID, in double x, in double y, in double z);
+
+ boolean InverseDiag(in long NodeID1, in long NodeID2);
+
+ boolean DeleteDiag(in long NodeID1, in long NodeID2);
+
+ boolean Reorient(in long_array IDsOfElements);
+
+ boolean ReorientObject(in SMESH_IDSource theObject);
+
+ /*!
+ * \brief Fuse neighbour triangles into quadrangles.
+ * \param theElems The triangles to be fused.
+ * \param theCriterion Is used to choose a neighbour to fuse with.
+ * \param theMaxAngle Is a max angle between element normals at which fusion
+ * is still performed; theMaxAngle is mesured in radians.
+ * \return TRUE in case of success, FALSE otherwise.
+ */
+ boolean TriToQuad (in long_array IDsOfElements,
+ in NumericalFunctor Criterion,
+ in double MaxAngle);
+
+ /*!
+ * \brief Fuse neighbour triangles into quadrangles.
+ *
+ * Behaves like the above method, taking list of elements from \a theObject
+ */
+ boolean TriToQuadObject (in SMESH_IDSource theObject,
+ in NumericalFunctor Criterion,
+ in double MaxAngle);
+
+ /*!
+ * \brief Split quadrangles into triangles.
+ * \param theElems The faces to be splitted.
+ * \param theCriterion Is used to choose a diagonal for splitting.
+ * \return TRUE in case of success, FALSE otherwise.
+ */
+ boolean QuadToTri (in long_array IDsOfElements,
+ in NumericalFunctor Criterion);
+
+ /*!
+ * \brief Split quadrangles into triangles.
+ *
+ * Behaves like the above method, taking list of elements from \a theObject
+ */
+ boolean QuadToTriObject (in SMESH_IDSource theObject,
+ in NumericalFunctor Criterion);
+
+ /*!
+ * \brief Split quadrangles into triangles.
+ * \param theElems The faces to be splitted.
+ * \param the13Diag Is used to choose a diagonal for splitting.
+ * \return TRUE in case of success, FALSE otherwise.
+ */
+ boolean SplitQuad (in long_array IDsOfElements,
+ in boolean Diag13);
+
+ /*!
+ * \brief Split quadrangles into triangles.
+ *
+ * Behaves like the above method, taking list of elements from \a theObject
+ */
+ boolean SplitQuadObject (in SMESH_IDSource theObject,
+ in boolean Diag13);
+
+ /*!
+ * Find better splitting of the given quadrangle.
+ * \param IDOfQuad ID of the quadrangle to be splitted.
+ * \param Criterion A criterion to choose a diagonal for splitting.
+ * \return 1 if 1-3 diagonal is better, 2 if 2-4
+ * diagonal is better, 0 if error occurs.
+ */
+ long BestSplit (in long IDOfQuad,
+ in NumericalFunctor Criterion);
+
+ enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
+
+ boolean Smooth(in long_array IDsOfElements,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
+ boolean SmoothObject(in SMESH_IDSource theObject,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
+ boolean SmoothParametric(in long_array IDsOfElements,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
+ boolean SmoothParametricObject(in SMESH_IDSource theObject,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
+ void ConvertToQuadratic(in boolean theForce3d);
+
+ boolean ConvertFromQuadratic();
+
+ void RenumberNodes();
+
+ void RenumberElements();
+
+ void RotationSweep(in long_array IDsOfElements,
+ in AxisStruct Axix,
+ in double AngleInRadians,
+ in long NbOfSteps,
+ in double Tolerance);
+
+ void RotationSweepObject(in SMESH_IDSource theObject,
+ in AxisStruct Axix,
+ in double AngleInRadians,
+ in long NbOfSteps,
+ in double Tolerance);
+
+ void ExtrusionSweep(in long_array IDsOfElements,
+ in DirStruct StepVector,
+ in long NbOfSteps);
+
+ /*!
+ * Generate new elements by extrusion of theElements
+ * by StepVector by NbOfSteps
+ * param ExtrFlags set flags for performing extrusion
+ * param SewTolerance - uses for comparing locations of nodes if flag
+ * EXTRUSION_FLAG_SEW is set
+ */
+ void AdvancedExtrusion(in long_array IDsOfElements,
+ in DirStruct StepVector,
+ in long NbOfSteps,
+ in long ExtrFlags,
+ in double SewTolerance);
+
+ void ExtrusionSweepObject(in SMESH_IDSource theObject,
+ in DirStruct StepVector,
+ in long NbOfSteps);
+
+ void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
+ in DirStruct StepVector,
+ in long NbOfSteps);
+
+ void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
+ in DirStruct StepVector,
+ in long NbOfSteps);
+
+ enum Extrusion_Error {
+ EXTR_OK,
+ EXTR_NO_ELEMENTS,
+ EXTR_PATH_NOT_EDGE,
+ EXTR_BAD_PATH_SHAPE,
+ EXTR_BAD_STARTING_NODE,
+ EXTR_BAD_ANGLES_NUMBER,
+ EXTR_CANT_GET_TANGENT
+ };
+
+ Extrusion_Error ExtrusionAlongPath(in long_array IDsOfElements,
+ in SMESH_Mesh PathMesh,
+ in GEOM::GEOM_Object PathShape,
+ in long NodeStart,
+ in boolean HasAngles,
+ in double_array Angles,
+ in boolean HasRefPoint,
+ in PointStruct RefPoint);
+
+ Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource theObject,
+ in SMESH_Mesh PathMesh,
+ in GEOM::GEOM_Object PathShape,
+ in long NodeStart,
+ in boolean HasAngles,
+ in double_array Angles,
+ in boolean HasRefPoint,
+ in PointStruct RefPoint);
+
+ /*!
+ * Compute rotation angles for ExtrusionAlongPath as linear variation
+ * of given angles along path steps
+ * param PathMesh mesh containing a 1D sub-mesh on the edge, along
+ * which proceeds the extrusion
+ * param PathShape is shape(edge); as the mesh can be complex, the edge
+ * is used to define the sub-mesh for the path
+ */
+ double_array LinearAnglesVariation(in SMESH_Mesh PathMesh,
+ in GEOM::GEOM_Object PathShape,
+ in double_array Angles);
+
+ enum MirrorType { POINT, AXIS, PLANE };
+
+ void Mirror (in long_array IDsOfElements,
+ in AxisStruct Mirror,
+ in MirrorType theMirrorType,
+ in boolean Copy);
+
+ void MirrorObject (in SMESH_IDSource theObject,
+ in AxisStruct Mirror,
+ in MirrorType theMirrorType,
+ in boolean Copy);
+
+ void Translate (in long_array IDsOfElements,
+ in DirStruct Vector,
+ in boolean Copy);
+
+ void TranslateObject (in SMESH_IDSource theObject,
+ in DirStruct Vector,
+ in boolean Copy);
+
+ void Rotate (in long_array IDsOfElements,
+ in AxisStruct Axis,
+ in double AngleInRadians,
+ in boolean Copy);
+
+ void RotateObject (in SMESH_IDSource theObject,
+ in AxisStruct Axis,
+ in double AngleInRadians,
+ in boolean Copy);
+
+ void FindCoincidentNodes (in double Tolerance,
+ out array_of_long_array GroupsOfNodes);
+
+ void FindCoincidentNodesOnPart (in SMESH_IDSource SubMeshOrGroup,
+ in double Tolerance,
+ out array_of_long_array GroupsOfNodes);
+
+ void MergeNodes (in array_of_long_array GroupsOfNodes);
+
+ /*!
+ * \brief Find elements built on the same nodes.
+ * \param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching.
+ * \return List of groups of equal elements.
+ */
+ void FindEqualElements (in SMESH_IDSource MeshOrSubMeshOrGroup,
+ out array_of_long_array GroupsOfElementsID);
+
+ /*!
+ * \brief Merge elements in each given group.
+ * \param GroupsOfElementsID Groups of elements for merging.
+ */
+ void MergeElements(in array_of_long_array GroupsOfElementsID);
+
+ /*!
+ * \brief Merge equal elements in the whole mesh.
+ */
+ void MergeEqualElements();
+
+ /*!
+ * If the given ID is a valid node ID (nodeID > 0), just move this node, else
+ * move the node closest to the point to point's location and return ID of the node
+ */
+ long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID);
+
+ enum Sew_Error {
+ SEW_OK,
+ SEW_BORDER1_NOT_FOUND,
+ SEW_BORDER2_NOT_FOUND,
+ SEW_BOTH_BORDERS_NOT_FOUND,
+ SEW_BAD_SIDE_NODES,
+ SEW_VOLUMES_TO_SPLIT,
+ // for SewSideElements() only:
+ SEW_DIFF_NB_OF_ELEMENTS,
+ SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
+ SEW_BAD_SIDE1_NODES,
+ SEW_BAD_SIDE2_NODES
+ };
+
+ Sew_Error SewFreeBorders (in long FirstNodeID1,
+ in long SecondNodeID1,
+ in long LastNodeID1,
+ in long FirstNodeID2,
+ in long SecondNodeID2,
+ in long LastNodeID2,
+ in boolean CreatePolygons,
+ in boolean CreatePolyedrs);
+
+ Sew_Error SewConformFreeBorders (in long FirstNodeID1,
+ in long SecondNodeID1,
+ in long LastNodeID1,
+ in long FirstNodeID2,
+ in long SecondNodeID2);
+
+ Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
+ in long SecondNodeIDOnFreeBorder,
+ in long LastNodeIDOnFreeBorder,
+ in long FirstNodeIDOnSide,
+ in long LastNodeIDOnSide,
+ in boolean CreatePolygons,
+ in boolean CreatePolyedrs);
+
+ Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
+ in long_array IDsOfSide2Elements,
+ in long NodeID1OfSide1ToMerge,
+ in long NodeID1OfSide2ToMerge,
+ in long NodeID2OfSide1ToMerge,
+ in long NodeID2OfSide2ToMerge);
+
+ /*!
+ * Set new nodes for given element.
+ * If number of nodes is not corresponded to type of
+ * element - returns false
+ */
+ boolean ChangeElemNodes(in long ide, in long_array newIDs);
+
+ /*!
+ * Return data of mesh edition preview which is computed provided
+ * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
+ */
+ MeshPreviewStruct GetPreviewData();
+
+ /*!
+ * If during last operation of MeshEditor some nodes were
+ * created this method returns list of it's IDs, if new nodes
+ * not creared - returns empty list
+ */
+ long_array GetLastCreatedNodes();
+
+ /*!
+ * If during last operation of MeshEditor some elements were
+ * created this method returns list of it's IDs, if new elements
+ * not creared - returns empty list
+ */
+ long_array GetLastCreatedElems();
+
+ };
+};
+
+#endif
mesh_tree_hypo_source_edge.png \
mesh_tree_hypo_source_3d_shape.png \
mesh_tree_hypo_projection_3d.png \
- mesh_tree_hypo_projection_2d.png
+ mesh_tree_hypo_projection_2d.png \
+ mesh_build_compound.png \
+ mesh_node_to_point.png \
+ mesh_tree_mesh_partial.png
nodist_salomeres_DATA = SMESHCatalog.xml
<popup-item item-id="121" pos-id="" label-id="DAT File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="122" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="123" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="140" pos-id="" label-id="STL File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<separator pos-id="10"/>
<separator pos-id=""/>
<popup-item item-id="122" pos-id="" label-id="Export to MED" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="123" pos-id="" label-id="Export to UNV" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="140" pos-id="" label-id="Export to STL" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="SubMesh">
<popup-item item-id="121" pos-id="" label-id="DAT File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="122" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="123" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="140" pos-id="" label-id="STL File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<separator pos-id="10"/>
gui-lib="StdMeshersGUI">
<hypotheses>
+ <hypothesis type="SegmentLengthAroundVertex"
+ label-id="Length Near Vertex"
+ icon-id="mesh_hypo_length.png"
+ dim="0"/>
+
<hypothesis type="LocalLength"
label-id="Average length"
icon-id="mesh_hypo_length.png"
<algorithms>
+ <algorithm type="SegmentAroundVertex_0D"
+ label-id="Segments around vertex"
+ icon-id="mesh_algo_regular.png"
+ hypos="SegmentLengthAroundVertex"
+ output="VERTEX"
+ dim="0"/>
+
<algorithm type="Regular_1D"
label-id="Wire discretisation"
icon-id="mesh_algo_regular.png"
output="EDGE"
dim="1"/>
+ <algorithm type="CompositeSegment_1D"
+ label-id="Composite side discretisation"
+ icon-id="mesh_algo_regular.png"
+ hypos="LocalLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength"
+ opt-hypos="Propagation,QuadraticMesh"
+ input="VERTEX"
+ output="EDGE"
+ dim="1"/>
+
<algorithm type="MEFISTO_2D"
label-id="Triangle (Mefisto)"
icon-id="mesh_algo_mefisto.png"
dim="3"/>
<algorithm type="Prism_3D"
- label-id="Prism 3D"
+ label-id="3D extrusion"
icon-id="mesh_algo_hexa.png"
input="QUAD,TRIA"
dim="3"/>
#include <set>
+#include <BRepAdaptor_Surface.hxx>
#include <BRep_Tool.hxx>
-#include <gp_Ax3.hxx>
-#include <gp_Cylinder.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Vec.hxx>
-#include <gp_XYZ.hxx>
-#include <Geom_Plane.hxx>
#include <Geom_CylindricalSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
#include <Precision.hxx>
-#include <TColgp_Array1OfXYZ.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_SequenceOfAsciiString.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <TColgp_Array1OfXYZ.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
+#include <gp_Ax3.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
#include "SMDS_Mesh.hxx"
#include "SMDS_Iterator.hxx"
myType = SMDSAbs_All;
mySurf.Nullify();
myToler = Precision::Confusion();
+ myUseBoundaries = false;
}
ElementsOnSurface::~ElementsOnSurface()
if ( myMesh == theMesh )
return;
myMesh = theMesh;
- myIds.Clear();
process();
}
{ return myType; }
void ElementsOnSurface::SetTolerance( const double theToler )
-{ myToler = theToler; }
+{
+ if ( myToler != theToler )
+ myIds.Clear();
+ myToler = theToler;
+}
double ElementsOnSurface::GetTolerance() const
+{ return myToler; }
+
+void ElementsOnSurface::SetUseBoundaries( bool theUse )
{
- return myToler;
+ if ( myUseBoundaries != theUse ) {
+ myUseBoundaries = theUse;
+ SetSurface( mySurf, myType );
+ }
}
void ElementsOnSurface::SetSurface( const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType )
{
+ myIds.Clear();
myType = theType;
mySurf.Nullify();
if ( theShape.IsNull() || theShape.ShapeType() != TopAbs_FACE )
- {
- mySurf.Nullify();
return;
- }
- TopoDS_Face aFace = TopoDS::Face( theShape );
- mySurf = BRep_Tool::Surface( aFace );
+ mySurf = TopoDS::Face( theShape );
+ BRepAdaptor_Surface SA( mySurf, myUseBoundaries );
+ Standard_Real
+ u1 = SA.FirstUParameter(),
+ u2 = SA.LastUParameter(),
+ v1 = SA.FirstVParameter(),
+ v2 = SA.LastVParameter();
+ Handle(Geom_Surface) surf = BRep_Tool::Surface( mySurf );
+ myProjector.Init( surf, u1,u2, v1,v2 );
+ process();
}
void ElementsOnSurface::process()
if ( myType == SMDSAbs_Face || myType == SMDSAbs_All )
{
+ myIds.ReSize( myMesh->NbFaces() );
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
for(; anIter->more(); )
process( anIter->next() );
if ( myType == SMDSAbs_Edge || myType == SMDSAbs_All )
{
+ myIds.ReSize( myMesh->NbEdges() );
SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
for(; anIter->more(); )
process( anIter->next() );
if ( myType == SMDSAbs_Node )
{
+ myIds.ReSize( myMesh->NbNodes() );
SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
for(; anIter->more(); )
process( anIter->next() );
myIds.Add( theElemPtr->GetID() );
}
-bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode ) const
+bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
{
if ( mySurf.IsNull() )
return false;
gp_Pnt aPnt( theNode->X(), theNode->Y(), theNode->Z() );
- double aToler2 = myToler * myToler;
- if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
- {
- gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
- if ( aPln.SquareDistance( aPnt ) > aToler2 )
- return false;
- }
- else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
- {
- gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
- double aRad = aCyl.Radius();
- gp_Ax3 anAxis = aCyl.Position();
- gp_XYZ aLoc = aCyl.Location().XYZ();
- double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
- double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
- if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
- return false;
- }
- else
- return false;
-
- return true;
+ // double aToler2 = myToler * myToler;
+// if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+// {
+// gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
+// if ( aPln.SquareDistance( aPnt ) > aToler2 )
+// return false;
+// }
+// else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+// {
+// gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
+// double aRad = aCyl.Radius();
+// gp_Ax3 anAxis = aCyl.Position();
+// gp_XYZ aLoc = aCyl.Location().XYZ();
+// double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+// double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+// if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
+// return false;
+// }
+// else
+// return false;
+ myProjector.Perform( aPnt );
+ bool isOn = ( myProjector.IsDone() && myProjector.LowerDistance() <= myToler );
+
+ return isOn;
}
#include <vector>
#include <boost/shared_ptr.hpp>
#include <gp_XYZ.hxx>
-#include <Geom_Surface.hxx>
+//#include <Geom_Surface.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TCollection_AsciiString.hxx>
+#include <TopoDS_Face.hxx>
#include "SMDSAbs_ElementType.hxx"
#include "SMDS_MeshNode.hxx"
class SMESHDS_SubMesh;
class gp_Pnt;
-class TopoDS_Shape;
+//class TopoDS_Shape;
namespace SMESH{
namespace Controls{
double GetTolerance() const;
void SetSurface( const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType );
+ void SetUseBoundaries( bool theUse );
+ bool GetUseBoundaries() const { return myUseBoundaries; }
private:
void process();
void process( const SMDS_MeshElement* theElem );
- bool isOnSurface( const SMDS_MeshNode* theNode ) const;
+ bool isOnSurface( const SMDS_MeshNode* theNode );
private:
const SMDS_Mesh* myMesh;
TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType;
- Handle(Geom_Surface) mySurf;
+ //Handle(Geom_Surface) mySurf;
+ TopoDS_Face mySurf;
double myToler;
+ bool myUseBoundaries;
+ GeomAPI_ProjectPointOnSurf myProjector;
};
typedef boost::shared_ptr<ElementsOnSurface> ElementsOnSurfacePtr;
// Storing SMDS groups and sub-meshes
//-----------------------------------
- int myNodesDefaultFamilyId = 0;
- int myEdgesDefaultFamilyId = 0;
- int myFacesDefaultFamilyId = 0;
+ int myNodesDefaultFamilyId = 0;
+ int myEdgesDefaultFamilyId = 0;
+ int myFacesDefaultFamilyId = 0;
int myVolumesDefaultFamilyId = 0;
- if (myDoGroupOfNodes)
+ int nbNodes = myMesh->NbNodes();
+ int nbEdges = myMesh->NbEdges();
+ int nbFaces = myMesh->NbFaces();
+ int nbVolumes = myMesh->NbVolumes();
+ if (myDoGroupOfNodes && nbNodes)
myNodesDefaultFamilyId = REST_NODES_FAMILY;
- if (myDoGroupOfEdges)
+ if (myDoGroupOfEdges && nbEdges)
myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
- if (myDoGroupOfFaces)
+ if (myDoGroupOfFaces && nbFaces)
myFacesDefaultFamilyId = REST_FACES_FAMILY;
- if (myDoGroupOfVolumes)
+ if (myDoGroupOfVolumes && nbVolumes)
myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
MESSAGE("Perform - aFamilyInfo");
if (myAllSubMeshes) {
aFamilies = DriverMED_Family::MakeFamilies
(myMesh->SubMeshes(), myGroups,
- myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+ myDoGroupOfNodes && nbNodes,
+ myDoGroupOfEdges && nbEdges,
+ myDoGroupOfFaces && nbFaces,
+ myDoGroupOfVolumes && nbVolumes);
} else {
aFamilies = DriverMED_Family::MakeFamilies
(mySubMeshes, myGroups,
- myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+ myDoGroupOfNodes && nbNodes,
+ myDoGroupOfEdges && nbEdges,
+ myDoGroupOfFaces && nbFaces,
+ myDoGroupOfVolumes && nbVolumes);
}
list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
#include "DriverUNV_W_SMDS_Mesh.h"
#include "SMDS_Mesh.hxx"
-#include "SMESHDS_GroupBase.hxx"
-//#include "SMESH_Group.hxx"
#include "SMDS_QuadraticEdge.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMESHDS_GroupBase.hxx"
#include "utilities.h"
TElementLab aLabel = anElem->GetID();
int aNbNodes = anElem->NbNodes();
- aConnect.resize(aNbNodes);
-
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ if ( anElem->IsPoly() ) {
+ if ( const SMDS_PolyhedralVolumeOfNodes* ph =
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+ {
+ aNbNodes = ph->NbUniqueNodes();
+ aNodesIter = ph->uniqueNodesIterator();
+ }
+ }
+ aConnect.resize(aNbNodes);
GetConnect(aNodesIter,aConnect);
int anId = -1;
// MEFISTO : library to compute 2D triangulation from segmented boundaries
//
-// Copyright (C) 2003 Laboratoire J.-L. Lions UPMC Paris
+// Copyright (C) 2006 Laboratoire J.-L. Lions UPMC Paris
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// File : Rn.h
// Module : SMESH
// Authors: Frederic HECHT & Alain PERRONNET
-//
+// Date : 13 novembre 2006
#ifndef Rn__h
#define Rn__h
//le type N des nombres entiers positifs
//=========
+#ifndef PCLINUX64
typedef unsigned long int N;
+#else
+typedef unsigned int N;
+#endif
//le type Z des nombres entiers relatifs
//=========
-// 64-bit porting: "long" replaced with "int".
-// On 64-bit, C++ long type is 8 byte long. MEFISTO2D C code calls several Fortran subroutines passing
-// arguments of this type, however Fortran knows nothing about changed size of arguments,
-// therefore stack gets corrupted. With "int" used instead of "long", Fortran calls from C do no harm to the stack
-// After this modification, behavior on 32-bit platforms does not change: on all platforms supported by
-// SALOME 3, "int" and "long" have the same size of 4 bytes.
-//========
-//typedef long int Z;
+#ifndef PCLINUX64
+typedef long int Z;
+#else
typedef int Z;
+#endif
//le type R des nombres "reels"
//=========
// MEFISTO2: a library to compute 2D triangulation from segmented boundaries
//
+//
// Copyright (C) 2006 Laboratoire J.-L. Lions UPMC Paris
//
// This library is free software; you can redistribute it and/or
// File : aptrte.cxx le C++ de l'appel du trianguleur plan
// Module : SMESH
// Author : Alain PERRONNET
-// Date : 16 mars 2006
+// Date : 13 novembre 2006
#include "Rn.h"
#include "aptrte.h"
R3 comxmi[2]; //coordonnees UV Min et Maximales
R aremin, aremax; //longueur minimale et maximale des aretes
+ R airemx; //aire maximale souhaitee d'un triangle
R quamoy, quamin;
Z noar0, noar, na;
Z i, l, n, ns, ns0, ns1, ns2, nosotr[3], nt;
Z mxsomm, nbsomm, nbarpi, nbarli, ndtri0, mn;
Z moins1=-1;
- R dist;
-
- aretemaxface_ = aretmx;
+ Z nuds = 0;
// initialisation du temps cpu
deltacpu_( d );
i = 4*nbarfr/10;
mxsomm = Max( 20000, 64*nbpti+i*i );
MESSAGE( "APTRTE: Debut de la triangulation plane avec " );
- MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx << " mxsomm=" << mxsomm );
+ MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx
+ << " mxsomm=" << mxsomm );
MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes");
NEWDEPART:
//l'arete precedente est dotee de sa suivante:celle cree ensuite
//les 2 coordonnees du sommet ns2 de la ligne
ns = ns1 - 1;
+//debut ajout 5/10/2006 ................................................
+ nuds = Max( nuds, ns ); //le numero du dernier sommet traite
+//fin ajout 5/10/2006 ................................................
mnpxyd[ns].x = uvslf[ns].x;
mnpxyd[ns].y = uvslf[ns].y;
mnpxyd[ns].z = areteideale();//( mnpxyd[ns], direction );
aremin = Min( aremin, d );
aremax = Max( aremax, d );
+//debut ajout du 5/10/2006 .............................................
+ //la longueur de l'arete ns1-ns2
+ d = sqrt( d );
+ //longueur arete = Min ( aretmx, aretes incidentes )
+ mnpxyd[ns ].z = Min( mnpxyd[ns ].z, d );
+ mnpxyd[ns2-1].z = Min( mnpxyd[ns2-1].z, d );
+//fin ajout du 5/10/2006 ...............................................
+
//le numero n de la ligne du sommet et son numero ns1 dans la ligne
mnslig[ns] = 1000000 * n + ns1-nudslf[n-1];
aremin = sqrt( aremin ); //longueur minimale d'une arete des lignes fermees
aremax = sqrt( aremax ); //longueur maximale d'une arete
- aretmx = Min( aretmx, aremax ); //pour homogeneiser
- MESSAGE("nutysu=" << nutysu << " aretmx=" << aretmx
- << " arete min=" << aremin << " arete max=" << aremax);
+//debut ajout 9/11/2006 ................................................
+ // devenu un commentaire aretmx = Min( aretmx, aremax ); //pour homogeneiser
+
+ // protection contre une arete max desiree trop grande ou trop petite
+ if( aretmx > aremax*2.05 ) aretmx = aremax;
+
+ // protection contre une arete max desiree trop petite
+ if( (aremax-aremin) > (aremin+aremax)*0.05 && aretmx < aremin*0.5 )
+ aretmx =(aremin+aremax*2)/3.0;
+
+ if( aretmx < aremin && aremin > 0 )
+ aretmx = aremin;
+
+ //sauvegarde pour la fonction areteideale_
+ aretemaxface_ = aretmx;
+
+ //aire maximale souhaitee des triangles
+ airemx = aretmx * aretmx * sqrt(3.0) / 2.0; //Aire triangle equilateral
+
+ for(i=0; i<=nuds; i++ )
+ mnpxyd[i].z = Min( mnpxyd[i].z, aretmx );
+ //MESSAGE("Numero du dernier sommet frontalier=" << nuds+1);
+//fin ajout 9/11/2006 .................................................
+
+
+ MESSAGE("Sur le bord: arete min=" << aremin << " arete max=" << aremax );
+ MESSAGE("Triangulation: arete mx=" << aretmx
+ << " triangle aire mx=" << airemx );
//chainage des aretes frontalieres : la derniere arete frontaliere
mnsoar[ mosoar * noar - mosoar + 5 ] = 0;
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
- qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
- nbt, quamoy, quamin );
+ qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+ nbt, quamoy, quamin );
// boucle sur les aretes internes (non sur une ligne de la frontiere)
// avec echange des 2 diagonales afin de rendre la triangulation delaunay
<< d << " secondes");
//qualites de la triangulation actuelle
- qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
- nbt, quamoy, quamin );
+ qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+ nbt, quamoy, quamin );
// detection des aretes frontalieres initiales perdues
// triangulation frontale pour les restaurer
terefr( nbarpi, mnpxyd,
mosoar, mxsoar, n1soar, mnsoar,
- moartr, n1artr, mnartr, mnarst,
+ moartr, mxartr, n1artr, mnartr, mnarst,
mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
n, ierr );
- MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere" );
+ MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere ierr=" << ierr );
deltacpu_( d );
tcpu += d;
MESSAGE("Temps de la recuperation des aretes perdues de la frontiere="
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
- qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
- nbt, quamoy, quamin );
+ qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+ nbt, quamoy, quamin );
// fin de la triangulation avec respect des aretes initiales frontalieres
deltacpu_( d );
tcpu += d;
- MESSAGE( "Temps de la suppression des triangles externes=" << d );
+ MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr );
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
- qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
- nbt, quamoy, quamin );
+ qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+ nbt, quamoy, quamin );
// amelioration de la qualite de la triangulation par
// barycentrage des sommets internes a la triangulation
cout << "aptrte: MC saturee mnarcf3=" << mnarcf3 << endl;
goto ERREUR;
}
- teamqt( nutysu,
- mnarst, mosoar, mxsoar, n1soar, mnsoar,
- moartr, mxartr, n1artr, mnartr,
- mxarcf, mnarcf2, mnarcf3,
- mn1arcf, mnarcf, mnarcf1,
- comxmi, nbarpi, nbsomm, mxsomm, mnpxyd, mnslig,
+ teamqt_( nutysu, aretmx, airemx,
+ mnarst, mosoar, mxsoar, n1soar, mnsoar,
+ moartr, mxartr, n1artr, mnartr,
+ mxarcf, mnarcf2, mnarcf3,
+ mn1arcf, mnarcf, mnarcf1,
+ nbarpi, nbsomm, mxsomm, mnpxyd, mnslig,
ierr );
if( mnarcf3 != NULL ) {delete [] mnarcf3; mnarcf3=NULL;}
if( mn1arcf != NULL ) {delete [] mn1arcf; mn1arcf=NULL;}
deltacpu_( d );
tcpu += d;
MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d );
- if( ierr != 0 ) goto ERREUR;
+ if( ierr == -13 ) ierr=0; //6/10/2006 arret de l'amelioration apres boucle infinie dans caetoi
+ if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation finale
- qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
- nbt, quamoy, quamin );
+ qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+ nbt, quamoy, quamin );
// renumerotation des sommets internes: mnarst(i)=numero final du sommet
// ===================================
}
nbt /= nbsttria; //le nombre final de triangles de la surface
MESSAGE( "APTRTE: Fin de la triangulation plane avec "<<nbst<<" sommets et "
- << nbt << " triangles=" << nbt);
+ << nbt << " triangles" );
deltacpu_( d );
tcpu += d;
MESSAGE( "APTRTE: Temps total de la triangulation plane=" << tcpu << " secondes" );
}
-void qualitetrte( R3 *mnpxyd,
- Z & mosoar, Z & mxsoar, Z *mnsoar,
- Z & moartr, Z & mxartr, Z *mnartr,
- Z & nbtria, R & quamoy, R & quamin )
+void qualitetrte_( R3 *mnpxyd,
+ Z & mosoar, Z & mxsoar, Z *mnsoar,
+ Z & moartr, Z & mxartr, Z *mnartr,
+ Z & nbtria, R & quamoy, R & quamin )
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : calculer la qualite moyenne et minimale de la triangulation
// ----- actuelle definie par les tableaux mnsoar et mnartr
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{
R d, aire, qualite;
- Z nosotr[3], mn, nbtrianeg, nt;
+ Z nosotr[3], mn, nbtrianeg, nt, ntqmin;
aire = 0;
quamoy = 0;
quamin = 2.0;
nbtria = 0;
nbtrianeg = 0;
+ ntqmin = 0;
mn = -moartr;
for ( nt=1; nt<=mxartr; nt++ )
quamoy += qualite;
//la qualite minimale
- quamin = Min( quamin, qualite );
+ if( qualite < quamin )
+ {
+ quamin = qualite;
+ ntqmin = nt;
+ }
//aire signee du triangle nt
d = surtd2( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1] );
<< " des " << nbtria << " triangles de surface plane totale="
<< aire);
+ if( quamin<0.3 )
+ {
+ //le numero des 3 sommets du triangle ntqmin de qualite minimale
+ nusotr_( ntqmin, mosoar, mnsoar, moartr, mnartr, nosotr );
+ MESSAGE("Triangle de qualite minimale "<<quamin<<" de sommets:"
+ <<nosotr[0]<<" "<<nosotr[1]<<" "<<nosotr[2]<<" ");
+ for (int i=0;i<3;i++)
+ MESSAGE("Sommet "<<nosotr[i]<<": x="<< mnpxyd[nosotr[i]-1].x
+ <<" y="<< mnpxyd[nosotr[i]-1].y);
+ }
+
if( nbtrianeg>0 )
- MESSAGE( "ATTENTION: nombre de triangles d'aire negative=" << nbtrianeg );
+ MESSAGE( "ATTENTION: "<< nbtrianeg << " TRIANGLES d'AIRE NEGATIVE" );
+
+ MESSAGE(" ");
return;
}
// SMESH MEFISTO2 : algorithm for meshing
//
-// Copyright (C) 2003 Laboratoire J.-L. Lions UPMC Paris
+// Copyright (C) 2006 Laboratoire J.-L. Lions UPMC Paris
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
//
// File : aptrte.h
-// Author: Alain PERRONNET
+// Author : Alain PERRONNET
// Module : SMESH
+// Date : 13 novembre 2006
#ifndef aptrte__h
#define aptrte__h
#define MEFISTO2D_EXPORT
#endif
- void qualitetrte( R3 *mnpxyd,
- Z & mosoar, Z & mxsoar, Z *mnsoar,
- Z & moartr, Z & mxartr, Z *mnartr,
- Z & nbtria, R & quamoy, R & quamin );
+extern "C" {
+void qualitetrte_( R3 *mnpxyd,
+ Z & mosoar, Z & mxsoar, Z *mnsoar,
+ Z & moartr, Z & mxartr, Z *mnartr,
+ Z & nbtria, R & quamoy, R & quamin ); }
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : calculer la qualite moyenne et minimale de la triangulation
// ----- actuelle definie par les tableaux nosoar et noartr
c MEFISTO : library to compute 2D triangulation from segmented boundaries
c
-c Copyright (C) 2003 Laboratoire J.-L. Lions UPMC Paris
+c Copyright (C) 2006 Laboratoire J.-L. Lions UPMC Paris
c
c This library is free software; you can redistribute it and/or
c modify it under the terms of the GNU Lesser General Public
c
c File : areteideale.f
c Module : SMESH
-c Author: Alain PERRONNET
+c Author : Alain PERRONNET
+c Date : 13 novembre 2006
double precision function areteideale( xyz, direction )
double precision xyz(3), direction(3)
c File : trte.f le Fortran du trianguleur plan
c Module : SMESH
c Author : Alain PERRONNET
-c Date : 16 mars 2006
+c Date : 13 novembre 2006
+
+ double precision function diptdr( pt , p1dr , p2dr )
+c++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++012
+c but : calculer la distance entre un point et une droite
+c ----- definie par 2 points p1dr et p2dr
+c
+c entrees :
+c ---------
+c pt : le point de R ** 2
+c p1dr p2dr : les 2 points de R ** 2 de la droite
+c++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++012
+c programmeur : alain perronnet analyse numrique paris janvier 1986
+c....................................................................012
+ double precision pt(2),p1dr(2),p2dr(2), a, b, c
+c
+c les coefficients de la droite a x + by + c =0
+ a = p2dr(2) - p1dr(2)
+ b = p1dr(1) - p2dr(1)
+ c = - a * p1dr(1) - b * p1dr(2)
+c
+c la distance = | a * x + b * y + c | / sqrt( a*a + b*b )
+ diptdr = abs( a * pt(1) + b * pt(2) + c ) / sqrt( a*a + b*b )
+ end
subroutine qutr2d( p1, p2, p3, qualite )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc mars 1997
c2345x7..............................................................012
+ parameter (lchain=6)
common / unites / lecteu, imprim, nunite(30)
integer nosoar(mosoar,mxsoar), noarst(*)
integer nu2sar(2)
+c
+ ierr = 0
c
c ajout eventuel de l'arete s1 s2 dans nosoar
nu2sar(1) = ns1
nosoar(4,noar) = nt1
c le triangle 2 de l'arete => le triangle nt2
nosoar(5,noar) = nt2
+c le chainage est mis a -1
+ nosoar(lchain,noar) = -1
c
c le sommet appartient a l'arete noar
noarst( nu2sar(1) ) = noar
c arete appartenant a plus de 2 triangles => erreur
if( ierr .ge. 0 ) then
write(imprim,*) 'erreur fasoar: arete ',noar,
- % ' dans 2 triangles et a creer!'
+ % ' dans 2 triangles',nosoar(4,noar),nosoar(5,noar),
+ % ' et ajouter',nt1,nt2
+ write(imprim,*)'arete',noar,(nosoar(i,noar),i=1,mosoar)
endif
- ierr = 2
- return
+c
+c ERREUR. CORRECTION POUR VOIR ...
+ nosoar(4,noar) = NT1
+ nosoar(5,noar) = NT2
+ccc ierr = 2
+ccc return
endif
endif
c
c mise a jour du numero des triangles de l'arete noar
c le triangle 2 de l'arete => le triangle nt1
- if( nosoar(4,noar) .lt. 0 ) then
+ if( nosoar(4,noar) .le. 0 ) then
c pas de triangle connu pour cette arete
n = 4
else
c deja un triangle connu. ce nouveau est le second
if( nosoar(5,noar) .gt. 0 .and. nt1 .gt. 0 .and.
- % nosoar(5,noar) .ne. nt1 ) then
+ % nosoar(5,noar) .ne. nt1 ) then
c arete appartenant a plus de 2 triangles => erreur
- write(imprim,*) 'erreur fasoar: arete ',noar,
- % ' dans plus de 2 triangles'
+ write(imprim,*) 'erreur fasoar: arete ',noar,
+ % ' dans triangles',nosoar(4,noar),nosoar(5,noar),
+ % ' et ajouter triangle',nt1
ierr = 3
return
endif
% nosoar(5,noar) .ne. nt2 ) then
c arete appartenant a plus de 2 triangles => erreur
write(imprim,*) 'erreur fasoar: arete ',noar,
+ % ' de st',nosoar(1,noar),'-',nosoar(2,noar),
% ' dans plus de 2 triangles'
ierr = 4
return
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : calcul des 2 coordonnees (xc,yc) dans le carre (0,1)
c ----- image par f:carre unite-->quadrangle appartenant a q1**2
-c par une resolution directe due a nicolas thenault
+c par une resolution directe due a Nicolas Thenault
c
c entrees:
c --------
if( letree(i,ntrp) .eq. 0 ) then
c la place i est libre
letree(i,ntrp) = -ns
+ ierr = 0
return
endif
10 continue
double precision a(2),s,aretmx,rac3
c
c protection du nombre de sommets avant d'ajouter ceux de tetree
+ ierr = 0
nbsofr = nbsomm
do 1 i = 1, nbsomm
comxmi(1,1) = min( comxmi(1,1), pxyd(1,i) )
comxmi(2,2) = max( comxmi(2,2), pxyd(2,i) )
1 continue
c
-c creation de l'arbre tee
-c =======================
+c creation de l'arbre letree
+c ==========================
c la premiere colonne vide de letree
letree(0,0) = 2
c chainage des te vides
subroutine tetaid( nutysu, dx, dy, longai, ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but : calculer la longueur de l'arete ideale en dx,dy
+c but : calculer la longueur de l'arete ideale longai en dx,dy
c -----
-c
c entrees:
c --------
c nutysu : numero de traitement de areteideale() selon le type de surface
c permtr : perimetre de la ligne enveloppe dans le plan
c avant mise a l'echelle a 2**20
c
-c modifies :
-c ----------
+c modifies:
+c ---------
c nbsomm : nombre de sommets apres identification
c pxyd : tableau des coordonnees 2d des points
c par point : x y distance_souhaitee
c
integer nuste(3)
equivalence (nuste(1),ns1),(nuste(2),ns2),(nuste(3),ns3)
+c
+ ierr = 0
c
c existence ou non de la fonction 'taille_ideale' des aretes
c autour du point. ici la carte est supposee isotrope
if( ierr .ne. 0 ) return
do 4 i=nbsom0+1,nbsomm
c mise a jour de taille_ideale des nouveaux sommets de te
- call tetaid( nutysu, pxyd(1,i), pxyd(2,i), pxyd(3,i), ierr )
+ call tetaid( nutysu, pxyd(1,i), pxyd(2,i),
+ % pxyd(3,i), ierr )
if( ierr .ne. 0 ) goto 9999
4 continue
endif
c
c quadrangle convexe : le critere de delaunay intervient
c ------------------ ---------------------------------
-c calcul du centre et rayon de la boule circonscrite a 123
+c calcul du centre et rayon de la boule circonscrite a ns123
c pas d'affichage si le triangle est degenere
ierr = -1
call cenced( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3), cetria,
c
c oui: ns4 est dans le cercle circonscrit a ns1 ns2 ns3
c => ns3 est aussi dans le cercle circonscrit de ns1 ns2 ns4
-c
-cccc les 2 triangles d'arete na sont effaces
-ccc do 25 j=4,5
-ccc nt = nosoar(j,na)
-cccc trace du triangle nt
-ccc call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc % ncnoir, ncjaun )
-ccc 25 continue
-c
c echange de la diagonale 12 par 34 des 2 triangles
call te2t2t( na, mosoar, n1soar, nosoar, noarst,
% moartr, noartr, na34 )
c les aretes internes peripheriques des 2 triangles sont enchainees
do 60 j=4,5
nt = nosoar(j,na34)
-cccc trace du triangle nt
-ccc call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc % ncoran, ncgric )
do 50 i=1,3
n = abs( noartr(i,nt) )
if( n .ne. na34 ) then
c retour en haut de la pile des aretes a traiter
goto 20
endif
+c
+ return
end
subroutine terefr( nbarpi, pxyd,
% mosoar, mxsoar, n1soar, nosoar,
- % moartr, n1artr, noartr, noarst,
+ % moartr, mxartr, n1artr, noartr, noarst,
% mxarcf, n1arcf, noarcf, larmin, notrcf,
% nbarpe, ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
c attention: mxsoar>3*mxsomm obligatoire!
c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre maximal de triangles declarables dans noartr
c mxarcf : nombre de variables des tableaux n1arcf, noarcf, larmin, notrcf
c
c modifies:
common / unites / lecteu,imprim,intera,nunite(29)
double precision pxyd(3,*)
integer nosoar(mosoar,mxsoar),
- % noartr(moartr,*),
+ % noartr(moartr,mxartr),
% noarst(*),
% n1arcf(0:mxarcf),
% noarcf(3,mxarcf),
% larmin(mxarcf),
% notrcf(mxarcf)
+c
+ ierr = 0
c
c le nombre d'aretes de la frontiere non arete de la triangulation
nbarpe = 0
c traitement de cette arete perdue ns1-ns2
call tefoar( narete, nbarpi, pxyd,
% mosoar, mxsoar, n1soar, nosoar,
- % moartr, n1artr, noartr, noarst,
+ % moartr, mxartr, n1artr, noartr, noarst,
% mxarcf, n1arcf, noarcf, larmin, notrcf,
% ierr )
if( ierr .ne. 0 ) return
cc++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc mai 1999
c2345x7..............................................................012
+ common / unites / lecteu,imprim,intera,nunite(29)
double precision pxyd(3,*)
integer nulftr(nblftr),nslign(nbsomm),
% nosoar(mosoar,mxsoar),
if( letrsu(nt) .ne. 0 .and.
% abs(letrsu(nt)) .ne. ligne ) goto 60
c
-cccc trace du triangle nt en couleur ligne0
-ccc call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc % ligne0, ncnoir )
-c
c le triangle est marque avec la valeur de ligne
letrsu(nt) = ligne
c
c temoin de ligne a traiter ensuite dans nulftr
nulftr(nl) = -abs( nulftr(nl) )
c
-cccc trace du triangle nt2 en jaune borde de magenta
-ccc call mttrtr( pxyd,nt2,
-ccc % moartr,noartr,mosoar,nosoar,
-ccc % ncjaun, ncmage )
-c
c l'arete est traitee
nosoar(6,na) = -3
c
end
-
- subroutine trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
+ subroutine trp1st( ns, noarst, mosoar, nosoar,
+ % moartr, mxartr, noartr,
% mxpile, lhpile, lapile )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : recherche des triangles de noartr partageant le sommet ns
c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
c chainage des aretes frontalieres, chainage du hachage des aretes
c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre de triangles declares dans noartr
c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
c mxpile : nombre maximal de triangles empilables
c
c sorties :
-c --------
+c ---------
c lhpile : >0 nombre de triangles empiles
c =0 si impossible de tourner autour du point
+c ou zero triangle contenant le sommet ns
c =-lhpile si apres butee sur la frontiere il y a a nouveau
c butee sur la frontiere . a ce stade on ne peut dire si tous
c les triangles ayant ce sommet ont ete recenses
c ce cas arrive seulement si le sommet est sur la frontiere
+c par un balayage de tous les triangles, lhpile donne le
+c nombre de triangles de sommet ns
+c remarque: si la pile est saturee recherche de tous les
+c triangles de sommet ns par balayage de tous les triangles
c lapile : numero dans noartr des triangles de sommet ns
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c auteur: alain perronnet analyse numerique paris upmc mars 1997
+c modifs: alain perronnet Laboratoire J-L. Lions UPMC Paris octobre 2006
c....................................................................012
common / unites / lecteu, imprim, nunite(30)
- integer noartr(moartr,*),
+ integer noartr(moartr,mxartr),
% nosoar(mosoar,*),
% noarst(*)
integer lapile(1:mxpile)
c la premiere arete de sommet ns
nar = noarst( ns )
if( nar .le. 0 ) then
- write(imprim,*) 'trp1st: sommet',ns,' sans arete'
- goto 9999
+ccc write(imprim,*) 'trp1st: sommet',ns,' sans arete'
+ goto 100
endif
c
c l'arete nar est elle active?
if( nosoar(1,nar) .le. 0 ) then
ccc write(imprim,*) 'trp1st: arete vide',nar,
ccc % ' st1:', nosoar(1,nar),' st2:',nosoar(2,nar)
- goto 9999
+ goto 100
endif
c
c le premier triangle de sommet ns
nt0 = abs( nosoar(4,nar) )
if( nt0 .le. 0 ) then
write(imprim,*) 'trp1st: sommet',ns,' dans aucun triangle'
- goto 9999
+ goto 100
endif
c
-c le triangle est il interne?
- if( noartr(1,nt0) .eq. 0 ) goto 9999
+c le triangle est il actif?
+ if( noartr(1,nt0) .eq. 0 ) goto 100
c
c le numero des 3 sommets du triangle nt0 dans le sens direct
call nusotr( nt0, mosoar, nosoar, moartr, noartr, nosotr )
do 5 nar=1,3
if( nosotr(nar) .eq. ns ) goto 10
5 continue
- nta = nt0
- goto 9995
+c pas de sommet ns dans le triangle nt0
+ goto 100
c
-c ns retrouve : le triangle nt0 est empile
+c ns retrouve : le triangle nt0 de sommet ns est empile
10 lhpile = 1
lapile(1) = nt0
nta = nt0
c le triangle nt1 oppose du triangle nt0 par l'arete noar
if( nosoar(4,noar) .eq. nt0 ) then
nt1 = nosoar(5,noar)
- else
+ else if( nosoar(5,noar) .eq. nt0 ) then
nt1 = nosoar(4,noar)
+ else
+ write(imprim,*)'trp1st: anomalie arete',noar,' sans triangle',nt0
+ goto 100
endif
c
c la boucle sur les triangles nt1 de sommet ns dans le sens indirect
do 20 nar=1,3
if( nosotr(nar) .eq. ns ) goto 25
20 continue
- nta = nt1
- goto 9995
+c pas de sommet ns dans le triangle nt1
+ goto 100
c
c nt1 est empile
- 25 if( lhpile .ge. mxpile ) goto 9990
+ 25 if( lhpile .ge. mxpile ) goto 100
lhpile = lhpile + 1
lapile(lhpile) = nt1
c
noar = abs( noartr(nar,nt1) )
if( nosoar(4,noar) .eq. nt1 ) then
nt1 = nosoar(5,noar)
- else
+ else if( nosoar(5,noar) .eq. nt1 ) then
nt1 = nosoar(4,noar)
+ else
+ write(imprim,*)'trp1st: Anomalie arete',noar,
+ % ' sans triangle',nt1
+ goto 100
endif
- if( nt1 .le. 0 ) goto 30
-c le triangle suivant est a l'exterieur
+c
+c le triangle suivant est il a l'exterieur?
+ if( nt1 .le. 0 ) goto 30
+c
+c non: est il le premier triangle de sommet ns?
if( nt1 .ne. nt0 ) goto 15
c
-c recherche terminee par arrivee sur nt0
+c oui: recherche terminee par arrivee sur nt0
c les triangles forment un "cercle" de "centre" ns
+c lhpile ressort avec le signe +
return
c
endif
c
-c pas de triangle voisin a nt1
-c ============================
+c pas de triangle voisin a nt1 qui doit etre frontalier
+c =====================================================
c le parcours passe par 1 des triangles exterieurs
c le parcours est inverse par l'arete de gauche
c le triangle nta est le premier triangle empile
do 32 nar=1,3
if( nosotr(nar) .eq. ns ) goto 33
32 continue
- goto 9995
+ goto 100
c
c l'arete qui precede (rotation / ns dans le sens direct)
33 if( nar .eq. 1 ) then
noar = abs( noartr(nar,nta) )
if( nosoar(4,noar) .eq. nta ) then
nt1 = nosoar(5,noar)
- else
+ else if( nosoar(5,noar) .eq. nta ) then
nt1 = nosoar(4,noar)
+ else
+ write(imprim,*)'trp1st: Anomalie arete',noar,
+ % ' SANS triangle',nta
+ goto 100
endif
if( nt1 .le. 0 ) then
c un seul triangle contient ns
- goto 70
+c parcours de tous les triangles pour lever le doute
+ goto 100
endif
c
c boucle sur les triangles de sommet ns dans le sens direct
do 50 nar=1,3
if( nosotr(nar) .eq. ns ) goto 60
50 continue
- nta = nt1
- goto 9995
+ goto 100
c
c nt1 est empile
- 60 if( lhpile .ge. mxpile ) goto 9990
+ 60 if( lhpile .ge. mxpile ) goto 70
lhpile = lhpile + 1
lapile(lhpile) = nt1
c
noar = abs( noartr(nar,nt1) )
c
c le triangle voisin de nta dans le sens direct
- nta = nt1
+ nta = nt1
if( nosoar(4,noar) .eq. nt1 ) then
nt1 = nosoar(5,noar)
- else
+ else if( nosoar(5,noar) .eq. nt1 ) then
nt1 = nosoar(4,noar)
+ else
+ write(imprim,*)'trp1st: anomalie arete',noar,
+ % ' SANS triangle',nt1
+ goto 100
endif
- nta = nt1
if( nt1 .gt. 0 ) goto 40
c
c butee sur le trou => fin des triangles de sommet ns
c ----------------------------------------------------
- 70 lhpile = -lhpile
-c impossible ici de trouver les autres triangles de sommet ns
+c impossible ici de trouver tous les triangles de sommet ns directement
c les triangles de sommet ns ne forment pas une boule de centre ns
+c au moins 1, voire 2 triangles frontaliers de sommet ns
+ 70 lhpile = -lhpile
+ return
+c
+c Balayage de tous les triangles actifs et de sommet ns
+c methode lourde et couteuse mais a priori tres fiable
+c -----------------------------------------------------
+ 100 lhpile = 0
+ do 120 nt1=1,mxartr
+ if( noartr(1,nt1) .ne. 0 ) then
+c le numero des 3 sommets du triangle i
+ call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr )
+ do 110 j=1,3
+ if( nosotr(j) .eq. ns ) then
+c le triangle contient le sommet ns
+ lhpile = lhpile + 1
+ if( lhpile .gt. mxpile ) goto 9990
+ lapile( lhpile ) = nt1
+ endif
+ 110 continue
+ endif
+ 120 continue
+c il n'est pas sur que ces triangles forment une boule de centre ns
+ lhpile = -lhpile
return
c
c saturation de la pile des triangles
c -----------------------------------
- 9990 write(imprim,*)'trp1st: saturation pile des triangles autour ',
- %'sommet',ns
- goto 9999
-c
-c erreur triangle ne contenant pas le sommet ns
-c ----------------------------------------------
- 9995 write(imprim,*) 'trp1st: triangle ',nta,' st=',
- % (nosotr(nar),nar=1,3),' sans le sommet' ,ns
+ 9990 write(imprim,*)'trp1st: saturation pile des triangles autour du so
+ %mmet',ns
+ write(imprim,*) 'Plus de',mxpile,' triangles de sommet',ns
+ write(imprim,19990) (ii,lapile(ii),ii=1,mxpile)
+19990 format(5(' triangle',i9))
c
9999 lhpile = 0
return
end
- subroutine tesusp( nbarpi, pxyd, noarst,
+ subroutine tesusp( quamal, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf, larmin, notrcf, liarcf,
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : supprimer de la triangulation les sommets de te trop proches
c ----- soit d'un sommet frontalier ou point interne impose
-c soit d'une arete frontaliere
+c soit d'une arete frontaliere si la qualite minimale des triangles
+c est inferieure a quamal
c
c attention: le chainage lchain de nosoar devient celui des cf
c
c entrees:
c --------
+c quamal : qualite des triangles au dessous de laquelle supprimer des sommets
c nbarpi : numero du dernier point interne impose par l'utilisateur
c pxyd : tableau des coordonnees 2d des points
c par point : x y distance_souhaitee
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc mars 1997
c....................................................................012
-c parameter ( quamal=0.3 ) => ok
-c parameter ( quamal=0.4 ) => pb pour le test ocean
-c parameter ( quamal=0.5 ) => pb pour le test ocean
-c
- parameter ( quamal=0.333, lchain=6 )
+ parameter ( lchain=6 )
common / unites / lecteu,imprim,intera,nunite(29)
- double precision pxyd(3,*), qualit
+ double precision pxyd(3,*), quamal, qualit, quaopt, quamin
integer nosoar(mosoar,mxsoar),
- % noartr(moartr,*),
+ % noartr(moartr,mxartr),
% noarst(*),
% n1arcf(0:mxarcf),
% noarcf(3,mxarcf),
equivalence (nosotr(1),ns1), (nosotr(2),ns2),
% (nosotr(3),ns3)
c
-cccc le nombre de sommets de te supprimes
-ccc nbstsu = 0
+c le nombre de sommets de te supprimes
+ nbstsu = 0
+ ierr = 0
c
c initialisation du chainage des aretes des cf => 0 arete de cf
do 10 narete=1,mxsoar
c ================================================================
do 100 ns = 1, nbarpi
c
-cccc le nombre de sommets supprimes pour ce sommet ns
-ccc nbsuns = 0
-c
+c le nombre de sommets supprimes pour ce sommet ns
+ nbsuns = 0
c la qualite minimale au dessous de laquelle le point proche
c interne est supprime
quaopt = quamal
endif
c
c recherche des triangles de sommet ns
-c ils doivent former un contour ferme de type etoile
- call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
+ call trp1st( ns, noarst, mosoar, nosoar,
+ % moartr, mxartr, noartr,
% mxarcf, nbtrcf, notrcf )
if( nbtrcf .eq. 0 ) goto 100
if( nbtrcf .lt. 0 ) then
-c erreur: impossible de trouver tous les triangles de sommet ns
-c seule une partie est a priori retrouvee
+c impossible de trouver tous les triangles de sommet ns
+c seule une partie est a priori retrouvee ce qui est normal
+c si ns est un sommet frontalier
nbtrcf = -nbtrcf
endif
c
c boucle sur les triangles de l'etoile du sommet ns
- quamin = 2.0
+c recherche du triangle de sommet ns ayant la plus basse qualite
+ quamin = 2.0d0
do 20 i=1,nbtrcf
-c
c le numero des 3 sommets du triangle nt
nt = notrcf(i)
- call nusotr( nt, mosoar, nosoar, moartr, noartr,
- % nosotr )
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
c nosotr(1:3) est en equivalence avec ns1, ns2, ns3
-c
c la qualite du triangle ns1 ns2 ns3
call qutr2d( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3), qualit )
if( qualit .lt. quamin ) then
c
c recherche du sommet de ntqmin le plus proche et non frontalier
c ==============================================================
-c le numero des 3 sommets du triangle nt
- call nusotr( ntqmin, mosoar, nosoar, moartr, noartr,
- % nosotr )
- nste = 0
- quamin = 1e28
+c le numero des 3 sommets du triangle ntqmin
+ call nusotr(ntqmin, mosoar, nosoar, moartr, noartr, nosotr)
+ nste = 0
+ d0 = 1e28
do 30 j=1,3
- if( nosotr(j) .ne. ns .and. nosotr(j) .gt. nbarpi ) then
- d = (pxyd(1,nosotr(j))-pxyd(1,ns))**2
- % + (pxyd(2,nosotr(j))-pxyd(2,ns))**2
- if( d .lt. quamin ) then
- quamin = d
- nste = j
+ nst = nosotr(j)
+ if( nst .ne. ns .and. nst .gt. nbarpi ) then
+ d = (pxyd(1,nst)-pxyd(1,ns))**2
+ % + (pxyd(2,nst)-pxyd(2,ns))**2
+ if( d .lt. d0 ) then
+ d0 = d
+ nste = j
endif
endif
30 continue
c nste est un sommet de triangle equilateral
c => le sommet nste va etre supprime
c ==========================================
- call te1stm( nste, pxyd, noarst,
+ call te1stm( nste, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf,
% larmin, notrcf, liarcf, ierr )
if( ierr .eq. 0 ) then
-cccc un sommet de te supprime de plus
-ccc nbstsu = nbstsu + 1
- goto 100
- else if( ierr .lt. 0 ) then
-c le sommet nste est externe donc non supprime
-c ou bien le sommet nste est le centre d'un cf dont toutes
-c les aretes simples sont frontalieres
-c dans les 2 cas le sommet n'est pas supprime
- ierr = 0
- goto 100
+c un sommet de te supprime de plus
+ nbstsu = nbstsu + 1
+c
+c boucle jusqu'a obtenir une qualite suffisante
+c si triangulation tres irreguliere =>
+c destruction de beaucoup de points internes
+c les 2 variables suivantes brident ces destructions massives
+ nbsuns = nbsuns + 1
+ quaopt = quaopt * 0.8
+ if( nbsuns .lt. 5 ) goto 15
else
-c erreur motivant un arret de la triangulation
- return
+ if( ierr .lt. 0 ) then
+c le sommet nste est externe donc non supprime
+c ou bien le sommet nste est le centre d'un cf dont toutes
+c les aretes simples sont frontalieres
+c dans les 2 cas le sommet n'est pas supprime
+ ierr = 0
+ goto 100
+ else
+c erreur motivant un arret de la triangulation
+ return
+ endif
endif
-c
-cccc boucle jusqu'a obtenir une qualite suffisante
-cccc si triangulation tres irreguliere =>
-cccc destruction de beaucoup de points internes
-cccc les 2 variables suivantes brident ces destructions massives
-ccc nbsuns = nbsuns + 1
-ccc quaopt = quaopt * 0.8
-ccc if( nbsuns .lt. 5 ) goto 15
endif
endif
c
100 continue
c
-c write(imprim,*)'retrait de',nbstsu,
-c % ' sommets de te trop proches de la frontiere'
+ write(imprim,*)'tesusp: suppression de',nbstsu,
+ % ' sommets de te trop proches de la frontiere'
return
end
- subroutine teamqa( nutysu,
+ subroutine teamqa( nutysu, airemx,
% noarst, mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
% mxtrcf, notrcf, nostbo,
% n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
+ % nbarpi, nbsomm, mxsomm, pxyd, nslign,
% ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but: si la taille de l'arete moyenne est >ampli*taille souhaitee
-c ---- alors ajout d'un sommet barycentre du plus grand triangle
+c but: Boucles sur les aretes actives de la triangulation actuelle
+c ---- si la taille de l'arete moyenne est >ampli*taille souhaitee
+c alors ajout d'un sommet barycentre du plus grand triangle
c de sommet ns
c si la taille de l'arete moyenne est <ampli/2*taille souhaitee
c alors suppression du sommet ns
c 1 il existe une fonction areteideale()
c dont seules les 2 premieres composantes de uv sont actives
c autres options a definir...
+c airemx : aire maximale d'un triangle
c noarst : noarst(i) numero d'une arete de sommet i
c mosoar : nombre maximal d'entiers par arete et
c indice dans nosoar de l'arete suivante dans le hachage
c numero du point dans le lexique point si interne impose
c 0 si le point est interne non impose par l'utilisateur
c -1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
c
c modifies :
c ----------
parameter (ampli=1.34d0,ampli2=ampli/2d0)
parameter (lchain=6)
common / unites / lecteu, imprim, nunite(30)
- double precision pxyd(3,*)
- double precision ponder, ponde1, xbar, ybar, x, y, surtd2
- double precision d, dmoy
- double precision d2d3(3,3)
- real origin(3), xyz(3)
- integer noartr(moartr,*),
- % nosoar(mosoar,*),
+ double precision pxyd(3,*), airemx
+ double precision ponder, ponde1, xbar, ybar, x, y, surtd2,
+ % xns, yns, airetm
+ double precision d, dmoy, dmax, dmin, dns, xyzns(3), s0, s1
+ integer noartr(moartr,mxartr),
+ % nosoar(mosoar,mxsoar),
% noarst(*),
% notrcf(mxtrcf),
% nslign(*),
% n1arcf(0:mxtrcf),
% noarcf(3,mxtrcf),
% larmin(mxtrcf)
- double precision comxmi(3,2)
integer nosotr(3)
c
+c initialisation du chainage des aretes des cf => 0 arete de cf
+ do 1 noar=1,mxsoar
+ nosoar( lchain, noar ) = -1
+ 1 continue
+ noar0 = 0
+c
c le nombre d'iterations pour ameliorer la qualite
- nbitaq = 4
+ nbitaq = 5
ier = 0
c
c initialisation du parcours
c
do 5000 iter=1,nbitaq
c
-c le nombre de sommets supprimes
- nbstsu = 0
- nbbaaj = 0
+cccc le nombre de barycentres ajoutes
+ccc nbbaaj = 0
c
c coefficient de ponderation croissant avec les iterations
- ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
+ ponder = 0.1d0 + iter * 0.5d0 / nbitaq
+ccc 9 octobre 2006 ponder = min( 1d0, 0.1d0 + iter * 0.9d0 / nbitaq )
+ccc 9 mars 2006 ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
ponde1 = 1d0 - ponder
c
c l'ordre du parcours dans le sens croissant ou decroissant
+c alternance du parcours
nt = nbs1
nbs1 = nbs2
nbs2 = nt
-c alternance du parcours
- nbs3 = -nbs3
+ nbs3 =-nbs3
c
do 1000 ns = nbs1, nbs2, nbs3
c
if( nslign(ns) .ne. 0 ) goto 1000
c
c existe-t-il une arete de sommet ns ?
- 10 noar = noarst( ns )
+ noar = noarst( ns )
if( noar .le. 0 ) goto 1000
+ if( nosoar(1,noar) .le. 0 ) goto 1000
c
c le 1-er triangle de l'arete noar
nt = nosoar( 4, noar )
c
c recherche des triangles de sommet ns
c ils doivent former un contour ferme de type etoile
- call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
+ call trp1st( ns, noarst, mosoar, nosoar,
+ % moartr, mxartr, noartr,
% mxtrcf, nbtrcf, notrcf )
if( nbtrcf .le. 0 ) goto 1000
c
-c mise a jour de la distance souhaitee
+c mise a jour de la distance souhaitee autour de ns
+ xns = pxyd(1,ns)
+ yns = pxyd(2,ns)
if( nutysu .gt. 0 ) then
c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,ns) dans le repere initial => xyz(1:3)
- call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
+ call tetaid( nutysu, xns, yns,
% pxyd(3,ns), ier )
endif
c
-c boucle sur les triangles qui forment une boule autour du sommet ns
- nbstbo = 0
-c chainage des aretes simples de la boule a rendre delaunay
+c boucle sur les triangles qui forment une etoile autour du sommet ns
+c chainage des aretes simples de l'etoile formee par ces triangles
+c
+c remise a zero du lien nosoar des aretes a rendre Delaunay
+ 19 if( noar0 .gt. 0 ) then
+ noar = nosoar(lchain,noar0)
+ nosoar(lchain,noar0) = -1
+ noar0 = noar
+ goto 19
+ endif
+c
noar0 = 0
+ nbstbo = 0
+ airetm = 0d0
do 40 i=1,nbtrcf
-c
-c le numero de l'arete du triangle nt ne contenant pas le sommet ns
+c recherche du triangle de plus grande aire
nt = notrcf(i)
+ call nusotr( nt, mosoar, nosoar,
+ % moartr, noartr, nosotr )
+ d = surtd2( pxyd(1,nosotr(1)),
+ % pxyd(1,nosotr(2)),
+ % pxyd(1,nosotr(3)) )
+ if( d .gt. airetm ) then
+ airetm = d
+ imax = i
+ else if( d .le. 0 ) then
+ write(imprim,*)'teamqa: triangle notrcf(',i,')=',
+ % notrcf(i),' st', nosotr,' AIRE=',d,'<=0'
+ goto 1000
+ endif
+c
+c le no de l'arete du triangle nt ne contenant pas le sommet ns
do 20 na=1,3
c le numero de l'arete na dans le tableau nosoar
noar = abs( noartr(na,nt) )
if( nosoar(1,noar) .ne. ns .and.
% nosoar(2,noar) .ne. ns ) goto 25
20 continue
+ write(imprim,*)'teamqa: ERREUR triangle',nt,
+ % ' SANS sommet',ns
c
c construction de la liste des sommets des aretes simples
c de la boule des triangles de sommet ns
do 30 j=nbstbo,1,-1
if( ns1 .eq. nostbo(j) ) goto 35
30 continue
-c ns1 est un nouveau sommet a ajouter
+c ns1 est un nouveau sommet a ajouter a l'etoile
nbstbo = nbstbo + 1
nostbo(nbstbo) = ns1
35 continue
c
-c noar est une arete potentielle a rendre delaunay
+c noar est une arete potentielle a rendre Delaunay
if( nosoar(3,noar) .eq. 0 ) then
c arete non frontaliere
nosoar(lchain,noar) = noar0
xbar = 0d0
ybar = 0d0
dmoy = 0d0
+ dmax = 0d0
+ dmin = 1d124
+ dns = 0d0
do 50 i=1,nbstbo
- x = pxyd(1,nostbo(i))
- y = pxyd(2,nostbo(i))
+ nst = nostbo(i)
+ x = pxyd(1,nst)
+ y = pxyd(2,nst)
xbar = xbar + x
ybar = ybar + y
- dmoy = dmoy + sqrt( (x-pxyd(1,ns))**2+(y-pxyd(2,ns))**2 )
+ d = sqrt( (x-xns)**2 + (y-yns)**2 )
+ dmoy = dmoy + d
+ dmax = max( dmax, d )
+ dmin = min( dmin, d )
+ dns = dns + pxyd(3,nst)
50 continue
+ xbar = xbar / nbstbo
+ ybar = ybar / nbstbo
dmoy = dmoy / nbstbo
+ dns = dns / nbstbo
c
c pas de modification de la topologie lors de la derniere iteration
c =================================================================
if( iter .eq. nbitaq ) goto 200
c
-c si la taille de l'arete moyenne est >ampli*taille souhaitee
+c si la taille de l'arete maximale est >ampli*taille souhaitee
c alors ajout d'un sommet barycentre du plus grand triangle
c de sommet ns
-c ===========================================================
- if( dmoy .gt. ampli*pxyd(3,ns) ) then
-c
- dmoy = 0d0
- do 150 i=1,nbtrcf
-c recherche du plus grand triangle en surface
- call nusotr( notrcf(i), mosoar, nosoar,
- % moartr, noartr, nosotr )
- d = surtd2( pxyd(1,nosotr(1)),
- % pxyd(1,nosotr(2)),
- % pxyd(1,nosotr(3)) )
- if( d .gt. dmoy ) then
- dmoy = d
- imax = i
- endif
- 150 continue
+c ============================================================
+ if( airetm .gt. airemx .or. dmax .gt. ampli*dns ) then
c
c ajout du barycentre du triangle notrcf(imax)
nt = notrcf( imax )
% + pxyd(i,nosotr(2))
% + pxyd(i,nosotr(3)) ) / 3d0
160 continue
-c
if( nutysu .gt. 0 ) then
c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
call tetaid( nutysu, pxyd(1,nbsomm), pxyd(2,nbsomm),
% pxyd(3,nbsomm), ier )
endif
call tr3str( nbsomm, nt,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
- % noarst,
- % nosotr, ierr )
+ % noarst, nosotr, ierr )
if( ierr .ne. 0 ) goto 9999
c
-c un barycentre ajoute de plus
- nbbaaj = nbbaaj + 1
+cccc un barycentre ajoute de plus
+ccc nbbaaj = nbbaaj + 1
c
c les aretes chainees de la boule sont rendues delaunay
goto 900
c
endif
c
-c si la taille de l'arete moyenne est <ampli/2*taille souhaitee
-c alors suppression du sommet ns
-c =============================================================
- if( dmoy .lt. ampli2*pxyd(3,ns) ) then
-c remise a -1 du chainage des aretes peripheriques de la boule ns
- noar = noar0
- 90 if( noar .gt. 0 ) then
-c protection du no de l'arete suivante
- na = nosoar(lchain,noar)
-c l'arete interne est remise a -1
- nosoar(lchain,noar) = -1
-c l'arete suivante
- noar = na
- goto 90
- endif
- call te1stm( ns, pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxtrcf, n1arcf, noarcf,
- % larmin, notrcf, nostbo,
- % ierr )
- if( ierr .eq. -543 ) then
- ierr = 0
- goto 1000
- else if( ierr .lt. 0 ) then
-c le sommet ns est externe donc non supprime
-c ou bien le sommet ns est le centre d'un cf dont toutes
-c les aretes simples sont frontalieres
-c dans les 2 cas le sommet ns n'est pas supprime
- ierr = 0
- goto 200
- else if( ierr .gt. 0 ) then
-c erreur irrecuperable
- goto 9999
- endif
- nbstsu = nbstsu + 1
- goto 1000
-c
- endif
-c
c les 2 coordonnees du barycentre des sommets des aretes
c simples de la boule du sommet ns
c ======================================================
- 200 xbar = xbar / nbstbo
- ybar = ybar / nbstbo
+C DEBUT AJOUT 10 octobre 2006
+C PONDERATION POUR EVITER LES DEGENERESCENSES AVEC PROTECTION
+C SI UN TRIANGLE DE SOMMET NS A UNE AIRE NEGATIVE APRES BARYCENTRAGE
+C ALORS LE SOMMET NS N'EST PAS BOUGE
+c
+c protection des XY du point initial
+ 200 xyzns(1) = pxyd(1,ns)
+ xyzns(2) = pxyd(2,ns)
+ xyzns(3) = pxyd(3,ns)
c
c ponderation pour eviter les degenerescenses
pxyd(1,ns) = ponde1 * pxyd(1,ns) + ponder * xbar
pxyd(2,ns) = ponde1 * pxyd(2,ns) + ponder * ybar
-c
if( nutysu .gt. 0 ) then
c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,ns) dans le repere initial => xyz(1:3)
call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
% pxyd(3,ns), ier )
endif
c
+c calcul des surfaces avant et apres deplacement de ns
+ s0 = 0d0
+ s1 = 0d0
+ do 210 i=1,nbtrcf
+c le numero de l'arete du triangle nt ne contenant pas le sommet ns
+ nt = notrcf(i)
+ do 204 na=1,3
+c le numero de l'arete na dans le tableau nosoar
+ noar = abs( noartr(na,nt) )
+ if( nosoar(1,noar) .ne. ns .and.
+ % nosoar(2,noar) .ne. ns ) then
+ ns2 = nosoar(1,noar)
+ ns3 = nosoar(2,noar)
+ goto 206
+ endif
+ 204 continue
+c aire signee des 2 triangles
+ 206 s0 = s0 + abs(surtd2(xyzns, pxyd(1,ns2),pxyd(1,ns3)))
+ s1 = s1 + abs(surtd2(pxyd(1,ns),pxyd(1,ns2),pxyd(1,ns3)))
+ 210 continue
+ if( abs(s0-s1) .gt. 1d-10*abs(s0) ) then
+c retour a la position initiale
+c car le point est passe au dela d'une arete de son etoile
+ pxyd(1,ns) = xyzns(1)
+ pxyd(2,ns) = xyzns(2)
+ pxyd(3,ns) = xyzns(3)
+c la ponderation est reduite 10 octobre 2006
+ ponder = max( 0.1d0, ponder*0.5d0 )
+ ponde1 = 1d0 - ponder
+ goto 1000
+ endif
+c
c les aretes chainees de la boule sont rendues delaunay
900 call tedela( pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar, noar0,
c
1000 continue
c
-ccc write(imprim,11000) nbstsu, nbbaaj
-ccc11000 format( i6,' sommets supprimes ' ,
-ccc % i6,' barycentres ajoutes' )
+ccc write(imprim,11000) iter, nbbaaj
+ccc11000 format('teamqa: iteration',i3,' =>',i6,' barycentres ajoutes')
c
c mise a jour pour ne pas oublier les nouveaux sommets
if( nbs1 .gt. nbs2 ) then
end
- subroutine teamsf( nutysu,
+ subroutine teamqt( nutysu, aretmx, airemx,
% noarst, mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
- % mxtrcf, notrcf, nostbo,
+ % mxarcf, notrcf, nostbo,
% n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
+ % nbarpi, nbsomm, mxsomm, pxyd, nslign,
% ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but : modification de la topologie des triangles autour des
-c ----- sommets frontaliers et mise en triangulation delaunay locale
+c but : amelioration de la qualite de la triangulation
+c -----
c
c entrees:
c --------
c 1 il existe une fonction areteideale()
c dont seules les 2 premieres composantes de uv sont actives
c autres options a definir...
+c aretmx : longueur maximale des aretes de la future triangulation
+c airemx : aire maximale souhaitee des triangles
c noarst : noarst(i) numero d'une arete de sommet i
c mosoar : nombre maximal d'entiers par arete et
c indice dans nosoar de l'arete suivante dans le hachage
c n1artr : numero du premier triangle vide dans le tableau noartr
c le chainage des triangles vides se fait sur noartr(2,.)
c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxtrcf : nombre maximal de triangles empilables
+c mxarcf : nombre maximal de triangles empilables
c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : >0 => ns numero du point dans le lexique point si interne impose
-c ou => 1 000 000 * n + ns1
-c ou n est le numero (1 a nblftr) de la ligne de ce point
-c ns1 est le numero du point dans sa ligne
-c = 0 si le point est interne non impose par l'utilisateur
-c =-1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
+c nslign : tableau du numero de sommet dans sa ligne pour chaque
+c sommet frontalier
+c numero du point dans le lexique point si interne impose
+c 0 si le point est interne non impose par l'utilisateur
+c -1 si le sommet est externe au domaine
c
c modifies :
c ----------
c
c auxiliaires:
c ------------
-c notrcf : tableau ( mxtrcf ) auxiliaire d'entiers
+c notrcf : tableau ( mxarcf ) auxiliaire d'entiers
c numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxtrcf ) auxiliaire d'entiers
+c nostbo : tableau ( mxarcf ) auxiliaire d'entiers
c numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxtrcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxtrcf) auxiliaire d'entiers
-c larmin : tableau ( mxtrcf ) auxiliaire d'entiers
+c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
+c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
+c larmin : tableau ( mxarcf ) auxiliaire d'entiers
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc janvier 1998
+c auteur : alain perronnet analyse numerique paris upmc juin 1997
c....................................................................012
- parameter (lchain=6)
+ double precision quamal
+c parameter ( quamal=0.3d0 ) => ok
+c parameter ( quamal=0.4d0 ) => pb pour le test ocean
+c parameter ( quamal=0.5d0 ) => pb pour le test ocean
+ parameter ( quamal=0.1d0 )
+c quamal=0.1d0 est choisi pour ne pas trop detruire de sommets
+c
common / unites / lecteu, imprim, nunite(30)
double precision pxyd(3,*)
- double precision a, angle, angled, pi, deuxpi, pis3
- double precision d2d3(3,3)
- real origin(3), xyz(3)
integer noartr(moartr,*),
% nosoar(mosoar,*),
% noarst(*),
- % notrcf(mxtrcf),
+ % notrcf(mxarcf),
% nslign(*),
- % nostbo(*),
- % n1arcf(0:mxtrcf),
- % noarcf(3,mxtrcf),
- % larmin(mxtrcf),
- % nosotr(3)
- double precision comxmi(3,2)
-c
-c le nombre d'iterations pour ameliorer la qualite
- nbitaq = 2
- ier = 0
-c
-c pi / 3
- pi = atan(1d0) * 4d0
- pis3 = pi / 3d0
- deuxpi = 2d0 * pi
-c
-c initialisation du parcours
- modifs = 0
- nbs1 = nbarpi
- nbs2 = 1
-c => pas de traitement sur les points des lignes de la frontiere
- nbs3 = -1
-c
- do 5000 iter=1,nbitaq
-c
-c le nombre de sommets supprimes
- nbstsu = 0
-c
-c l'ordre du parcours dans le sens croissant ou decroissant
- nt = nbs1
- nbs1 = nbs2
- nbs2 = nt
-c alternance du parcours
- nbs3 = -nbs3
+ % nostbo(mxarcf),
+ % n1arcf(0:mxarcf),
+ % noarcf(3,mxarcf),
+ % larmin(mxarcf)
+ double precision aretmx, airemx
+ double precision quamoy, quamin
c
- do 1000 ns = nbs1, nbs2, nbs3
+ ierr = 0
c
-c le sommet est il sur une ligne de la frontiere?
-c if( nslign(ns) .lt. 1 000 000 ) goto 1000
+c supprimer de la triangulation les triangles de qualite
+c inferieure a quamal
+c ======================================================
+ call tesuqm( quamal, nbarpi, pxyd, noarst,
+ % mosoar, mxsoar, n1soar, nosoar,
+ % moartr, mxartr, n1artr, noartr,
+ % mxarcf, n1arcf, noarcf,
+ % larmin, notrcf, nostbo,
+ % quamin )
+ call qualitetrte( pxyd, mosoar, mxsoar, nosoar,
+ % moartr, mxartr, noartr,
+ % nbtria, quamoy, quamin )
c
-c traitement d'un sommet d'une ligne de la frontiere
-c ==================================================
-c existe-t-il une arete de sommet ns ?
- noar = noarst( ns )
- if( noar .le. 0 ) goto 1000
+c suppression des sommets de triangles equilateraux trop proches
+c d'un sommet frontalier ou d'un point interne impose par
+c triangulation frontale de l'etoile et mise en delaunay
+c ==============================================================
+ if( quamin .le. quamal ) then
+ call tesusp( quamal, nbarpi, pxyd, noarst,
+ % mosoar, mxsoar, n1soar, nosoar,
+ % moartr, mxartr, n1artr, noartr,
+ % mxarcf, n1arcf, noarcf,
+ % larmin, notrcf, nostbo,
+ % ierr )
+ if( ierr .ne. 0 ) goto 9999
+ endif
c
-c le 1-er triangle de l'arete noar
- nt = nosoar( 4, noar )
- if( nt .le. 0 ) goto 1000
+c ajustage des tailles moyennes des aretes avec ampli=1.34d0 entre
+c ampli/2 x taille_souhaitee et ampli x taille_souhaitee
+c + barycentrage des sommets et mise en triangulation delaunay
+c ================================================================
+ call teamqa( nutysu, airemx,
+ % noarst, mosoar, mxsoar, n1soar, nosoar,
+ % moartr, mxartr, n1artr, noartr,
+ % mxarcf, notrcf, nostbo,
+ % n1arcf, noarcf, larmin,
+ % nbarpi, nbsomm, mxsomm, pxyd, nslign,
+ % ierr )
+ call qualitetrte( pxyd, mosoar, mxsoar, nosoar,
+ % moartr, mxartr, noartr,
+ % nbtria, quamoy, quamin )
+ if( ierr .ne. 0 ) goto 9999
c
-c recherche des triangles de sommet ns
-c ils doivent former un contour ferme de type camembert
- call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
- % mxtrcf, nbtrcf, notrcf )
- if( nbtrcf .ge. -1 ) goto 1000
+ 9999 return
+ end
+
+ subroutine trfrcf( nscent, mosoar, nosoar, moartr, noartr,
+ % nbtrcf, notrcf, nbarfr )
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but : calculer le nombre d'aretes simples du contour ferme des
+c ----- nbtrcf triangles de numeros stockes dans le tableau notrcf
+c ayant tous le sommet nscent
c
-c boucle sur les triangles qui forment un camembert autour du sommet n
- nbtrcf = -nbtrcf
+c entrees:
+c --------
+c nscent : numero du sommet appartenant a tous les triangles notrcf
+c mosoar : nombre maximal d'entiers par arete et
+c indice dans nosoar de l'arete suivante dans le hachage
+c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
+c chainage des aretes frontalieres, chainage du hachage des aretes
+c moartr : nombre maximal d'entiers par arete du tableau noartr
+c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
+c nbtrcf : >0 nombre de triangles empiles
+c =0 si impossible de tourner autour du point
+c =-nbtrcf si apres butee sur la frontiere il y a a nouveau
+c butee sur la frontiere . a ce stade on ne peut dire si tous
+c les triangles ayant ce sommet ont ete recenses
+c ce cas arrive seulement si le sommet est sur la frontiere
+c notrcf : numero dans noartr des triangles de sommet ns
c
-c angle interne au camembert autour du sommet ns
- angle = 0d0
- do 540 i=1,nbtrcf
-c
-c le numero de l'arete du triangle nt ne contenant pas le sommet ns
- nt = notrcf(i)
- do 520 na=1,3
-c le numero de l'arete na dans le tableau nosoar
- noar = abs( noartr(na,nt) )
- if( nosoar(1,noar) .ne. ns .and.
- % nosoar(2,noar) .ne. ns ) goto 525
- 520 continue
-c
-c calcul de l'angle (ns-st1 arete, ns-st2 arete)
- 525 ns1 = nosoar(1,noar)
- ns2 = nosoar(2,noar)
- a = angled( pxyd(1,ns), pxyd(1,ns1), pxyd(1,ns2) )
- if( a .gt. pi ) a = deuxpi - a
- angle = angle + a
-c
- 540 continue
-c
-c nombre ideal de triangles autour du sommet ns
- n = nint( angle / pis3 )
- if( n .le. 1 ) goto 1000
- i = 1
- if( nbtrcf .gt. n ) then
-c
-c ajout du barycentre du triangle "milieu"
- nt = notrcf( (n+1)/2 )
- call nusotr( nt, mosoar, nosoar,
- % moartr, noartr, nosotr )
- if( nbsomm .ge. mxsomm ) then
- write(imprim,*) 'saturation du tableau pxyd'
-c abandon de l'amelioration du sommet ns
- goto 1000
- endif
- nbsomm = nbsomm + 1
- do 560 i=1,3
- pxyd(i,nbsomm) = ( pxyd(i,nosotr(1))
- % + pxyd(i,nosotr(2))
- % + pxyd(i,nosotr(3)) ) / 3d0
- 560 continue
-c
- if( nutysu .gt. 0 ) then
-c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
- call tetaid( nutysu, pxyd(1,nbsomm), pxyd(2,nbsomm),
- % pxyd(3,nbsomm), ier )
- endif
-c
-c sommet interne a la triangulation
- nslign(nbsomm) = 0
-c
-c les 3 aretes du triangle nt sont a rendre delaunay
- noar0 = 0
- do 570 i=1,3
- noar = abs( noartr(i,nt) )
- if( nosoar(3,noar) .eq. 0 ) then
-c arete non frontaliere
- if( nosoar(lchain,noar) .lt. 0 ) then
-c arete non encore chainee
- nosoar(lchain,noar) = noar0
- noar0 = noar
- endif
- endif
- 570 continue
-c
-c triangulation du triangle de barycentre nbsomm
-c protection a ne pas modifier sinon erreur!
- call tr3str( nbsomm, nt,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % noarst,
- % nosotr, ierr )
- if( ierr .ne. 0 ) goto 9999
-c
-c les aretes chainees de la boule sont rendues delaunay
- call tedela( pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar, noar0,
- % moartr, mxartr, n1artr, noartr, modifs )
- endif
-c
- 1000 continue
-c
- 5000 continue
-c
- 9999 return
- end
-
-
- subroutine teamqs( nutysu,
- % noarst, mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxtrcf, notrcf, nostbo,
- % n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
- % ierr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but : une iteration de barycentrage des points internes
-c ----- modification de la topologie pour avoir 4 ou 5 ou 6 triangles
-c pour chaque sommet de la triangulation
-c mise en triangulation delaunay
-c
-c entrees:
-c --------
-c nutysu : numero de traitement de areteideale() selon le type de surface
-c 0 pas d'emploi de la fonction areteideale() => aretmx active
-c 1 il existe une fonction areteideale()
-c dont seules les 2 premieres composantes de uv sont actives
-c autres options a definir...
-c noarst : noarst(i) numero d'une arete de sommet i
-c mosoar : nombre maximal d'entiers par arete et
-c indice dans nosoar de l'arete suivante dans le hachage
-c mxsoar : nombre maximal d'aretes frontalieres declarables
-c n1soar : numero de la premiere arete vide dans le tableau nosoar
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c mxartr : nombre maximal de triangles declarables dans noartr
-c n1artr : numero du premier triangle vide dans le tableau noartr
-c le chainage des triangles vides se fait sur noartr(2,.)
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxtrcf : nombre maximal de triangles empilables
-c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : >0 => ns numero du point dans le lexique point si interne impose
-c ou => 1 000 000 * n + ns1
-c ou n est le numero (1 a nblftr) de la ligne de ce point
-c ns1 est le numero du point dans sa ligne
-c = 0 si le point est interne non impose par l'utilisateur
-c =-1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
-c
-c modifies :
-c ----------
-c nbsomm : nombre actuel de sommets de la triangulation
-c (certains sommets internes ont ete desactives ou ajoutes)
-c pxyd : tableau des coordonnees 2d des points
-c
-c auxiliaires:
-c ------------
-c notrcf : tableau ( mxtrcf ) auxiliaire d'entiers
-c numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxtrcf ) auxiliaire d'entiers
-c numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxtrcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxtrcf) auxiliaire d'entiers
-c larmin : tableau ( mxtrcf ) auxiliaire d'entiers
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : Alain Perronnet Laboratoire J.-L. LIONS Paris UPMC mars 2006
-c....................................................................012
- parameter (lchain=6)
- common / unites / lecteu, imprim, nunite(30)
- double precision pxyd(3,*)
- double precision ponder, ponde1, xbar, ybar, x, y, d, dmin, dmax
- double precision surtd2
- double precision d2d3(3,3)
- real origin(3), xyz(3)
- integer noartr(moartr,*),
- % nosoar(mosoar,*),
- % noarst(*),
- % notrcf(mxtrcf),
- % nslign(*),
- % nostbo(*),
- % n1arcf(0:mxtrcf),
- % noarcf(3,mxtrcf),
- % larmin(mxtrcf)
- integer nosotr(3,2)
- double precision comxmi(3,2)
-c
-c le nombre d'iterations pour ameliorer la qualite
- nbitaq = 6
- ier = 0
-c
-c initialisation du parcours
- nbs1 = nbsomm
- nbs2 = nbarpi + 1
-c => pas de traitement sur les points des lignes de la frontiere
- nbs3 = -1
-c
- do 5000 iter=1,nbitaq
-c
-c le nombre de sommets supprimes
- nbstsu = 0
-c
-c les compteurs de passage sur les differents cas
- nbst4 = 0
- nbst5 = 0
- nbst8 = 0
-c
-c coefficient de ponderation croissant avec les iterations
- ponder = min( 1d0, 0.1d0 + iter * 0.9d0 / nbitaq )
-ccc 9 mars 2006 ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
- ponde1 = 1d0 - ponder
-c
-c l'ordre du parcours dans le sens croissant ou decroissant
- nt = nbs1
- nbs1 = nbs2
- nbs2 = nt
-c alternance du parcours
- nbs3 = -nbs3
-c
- do 1000 ns = nbs1, nbs2, nbs3
-c
-c le sommet est il interne au domaine?
- if( nslign(ns) .ne. 0 ) goto 1000
-c
-c traitement d'un sommet interne non impose par l'utilisateur
-c ===========================================================
-c existe-t-il une arete de sommet ns ?
- 10 noar = noarst( ns )
- if( noar .le. 0 ) goto 1000
-c
-c le 1-er triangle de l'arete noar
- nt = nosoar( 4, noar )
- if( nt .le. 0 ) goto 1000
-c
-c recherche des triangles de sommet ns
-c ils doivent former un contour ferme de type etoile
- call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
- % mxtrcf, nbtrcf, notrcf )
- if( nbtrcf .le. 2 ) goto 1000
-c
-c boucle sur les triangles qui forment une boule autour du sommet ns
- nbstbo = 0
-c chainage des aretes simples de la boule a rendre delaunay
- noar0 = 0
- do 40 i=1,nbtrcf
-c
-c le numero de l'arete du triangle nt ne contenant pas le sommet ns
- nt = notrcf(i)
- do 20 na=1,3
-c le numero de l'arete na dans le tableau nosoar
- noar = abs( noartr(na,nt) )
- if( nosoar(1,noar) .ne. ns .and.
- % nosoar(2,noar) .ne. ns ) goto 25
- 20 continue
-c
-c construction de la liste des sommets des aretes simples
-c de la boule des triangles de sommet ns
-c -------------------------------------------------------
- 25 do 35 na=1,2
- ns1 = nosoar(na,noar)
- do 30 j=nbstbo,1,-1
- if( ns1 .eq. nostbo(j) ) goto 35
- 30 continue
-c ns1 est un nouveau sommet a ajouter
- nbstbo = nbstbo + 1
- nostbo(nbstbo) = ns1
- 35 continue
-c
-c noar est une arete potentielle a rendre delaunay
- if( nosoar(3,noar) .eq. 0 ) then
-c arete non frontaliere
- nosoar(lchain,noar) = noar0
- noar0 = noar
- endif
-c
- 40 continue
-c
-c calcul des 2 coordonnees du barycentre de la boule du sommet ns
-c calcul de l'arete de taille maximale et minimale issue de ns
-c ---------------------------------------------------------------
- xbar = 0d0
- ybar = 0d0
- dmin = 1d28
- dmax = 0d0
- do 50 i=1,nbstbo
- x = pxyd(1,nostbo(i))
- y = pxyd(2,nostbo(i))
- xbar = xbar + x
- ybar = ybar + y
- d = (x-pxyd(1,ns)) ** 2 + (y-pxyd(2,ns)) ** 2
- if( d .gt. dmax ) then
- dmax = d
- imax = i
- endif
- if( d .lt. dmin ) then
- dmin = d
- imin = i
- endif
- 50 continue
-c
-c pas de modification de la topologie lors de la derniere iteration
-c =================================================================
- if( iter .ge. nbitaq ) goto 200
-c
-c si la boule de ns contient au plus 3 triangles
-c => pas de changement de topologie
-c ==============================================
- if( nbtrcf .le. 3 ) goto 200
-c
-c si la boule de ns contient 4 triangles le sommet ns est detruit
-c ===============================================================
- if( nbtrcf .eq. 4 ) then
-c
-c remise a -1 du chainage des aretes peripheriques de la boule ns
- noar = noar0
- 60 if( noar .gt. 0 ) then
-c protection du no de l'arete suivante
- na = nosoar(lchain,noar)
-c l'arete interne est remise a -1
- nosoar(lchain,noar) = -1
-c l'arete suivante
- noar = na
- goto 60
- endif
- call te1stm( ns, pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxtrcf, n1arcf, noarcf,
- % larmin, notrcf, nostbo,
- % ierr )
- if( ierr .eq. -543 ) then
- ierr = 0
- goto 1000
- else if( ierr .lt. 0 ) then
-c le sommet ns est externe donc non supprime
-c ou bien le sommet ns est le centre d'un cf dont toutes
-c les aretes simples sont frontalieres
-c dans les 2 cas le sommet ns n'est pas supprime
- ierr = 0
- goto 200
- else if( ierr .eq. 0 ) then
- nbst4 = nbst4 + 1
- nbstsu = nbstsu + 1
- else
-c erreur irrecuperable
- write(imprim,*)
- % 'teamqs: erreur1 irrecuperable en sortie te1stm'
- goto 9999
- endif
- goto 1000
-c
- endif
-c
-c si la boule de ns contient 5 triangles et a un sommet voisin
-c sommet de 5 triangles alors l'arete joignant ces 2 sommets
-c est transformee en un seul sommet de 6 triangles
-c ============================================================
- if( nbtrcf .eq. 5 ) then
-c
- do 80 i=1,5
-c le numero du sommet de l'arete i et different de ns
- ns1 = nostbo(i)
-c la liste des triangles de sommet ns1
- call trp1st( ns1, noarst,
- % mosoar, nosoar, moartr, noartr,
- % mxtrcf-5, nbtrc1, notrcf(6) )
- if( nbtrc1 .eq. 5 ) then
-c
-c l'arete de sommets ns-ns1 devient un point
-c par suppression du sommet ns
-c
-c remise a -1 du chainage des aretes peripheriques de la boul
- noar = noar0
- 70 if( noar .gt. 0 ) then
-c protection du no de l'arete suivante
- na = nosoar(lchain,noar)
-c l'arete interne est remise a -1
- nosoar(lchain,noar) = -1
-c l'arete suivante
- noar = na
- goto 70
- endif
-c
-c le point ns1 devient le milieu de l'arete ns-ns1
- x = pxyd(1,ns1)
- y = pxyd(2,ns1)
- d = pxyd(3,ns1)
- do 75 j=1,3
- pxyd(j,ns1) = (pxyd(j,ns) + pxyd(j,ns1)) * 0.5d0
- 75 continue
-c
- if( nutysu .gt. 0 ) then
-c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,ns1) dans le repere initial => xyz(1:3
- call tetaid( nutysu,pxyd(1,ns1),pxyd(2,ns1),
- % pxyd(3,ns1), ier )
- endif
-c
-c suppression du point ns et mise en delaunay
- call te1stm( ns, pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxtrcf, n1arcf, noarcf,
- % larmin, notrcf, nostbo,
- % ierr )
- if( ierr .lt. 0 ) then
-c le sommet ns est externe donc non supprime
-c ou bien le sommet ns est le centre d'un cf dont toutes
-c les aretes simples sont frontalieres ou erreur
-c dans les 3 cas le sommet ns n'est pas supprime
-c restauration du sommet ns1 a son ancienne place
- pxyd(1,ns1) = x
- pxyd(2,ns1) = y
- pxyd(3,ns1) = d
- ierr = 0
- goto 1000
- else if( ierr .eq. 0 ) then
- nbstsu = nbstsu + 1
- nbst5 = nbst5 + 1
- goto 1000
- else
-c erreur irrecuperable
- write(imprim,*)
- % 'teamqs: erreur2 irrecuperable en sortie te1stm'
- goto 9999
- endif
- endif
- 80 continue
- endif
-c
-c si la boule de ns contient au moins 8 triangles
-c alors un triangle interne est ajoute + 3 triangles (1 par arete)
-c ================================================================
- if( nbtrcf .ge. 8 ) then
-c
-c modification des coordonnees du sommet ns
-c il devient le barycentre du triangle notrcf(1)
- call nusotr( notrcf(1), mosoar, nosoar,
- % moartr, noartr, nosotr )
- do 110 i=1,3
- pxyd(i,ns) = ( pxyd(i,nosotr(1,1))
- % + pxyd(i,nosotr(2,1))
- % + pxyd(i,nosotr(3,1)) ) / 3d0
- 110 continue
-c
- if( nutysu .gt. 0 ) then
-c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
- call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
- % pxyd(3,ns), ier )
- endif
-c
-c ajout des 2 autres sommets comme barycentres des triangles
-c notrcf(1+nbtrcf/3) et notrcf(1+2*nbtrcf/3)
- nbt1 = ( nbtrcf + 1 ) / 3
- do 140 n=1,2
-c
-c le triangle traite
- nt = notrcf(1 + n * nbt1 )
-c
-c le numero pxyd de ses 3 sommets
- call nusotr( nt, mosoar, nosoar,
- % moartr, noartr, nosotr )
-c
-c ajout du nouveau barycentre
- if( nbsomm .ge. mxsomm ) then
- write(imprim,*) 'teamqs: saturation du tableau pxyd'
-c abandon de l'amelioration
- goto 9999
- endif
- nbsomm = nbsomm + 1
- do 120 i=1,3
- pxyd(i,nbsomm) = ( pxyd(i,nosotr(1,1))
- % + pxyd(i,nosotr(2,1))
- % + pxyd(i,nosotr(3,1)) ) / 3d0
- 120 continue
-c
- if( nutysu .gt. 0 ) then
-c la fonction taille_ideale(x,y,z) existe
-c calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3
- call tetaid( nutysu, pxyd(1,nbsomm),pxyd(2,nbsomm),
- % pxyd(3,nbsomm), ier )
- endif
-c
-c sommet interne a la triangulation
- nslign(nbsomm) = 0
-c
-c les 3 aretes du triangle nt sont a rendre delaunay
- do 130 i=1,3
- noar = abs( noartr(i,nt) )
- if( nosoar(3,noar) .eq. 0 ) then
-c arete non frontaliere
- if( nosoar(lchain,noar) .lt. 0 ) then
-c arete non encore chainee
- nosoar(lchain,noar) = noar0
- noar0 = noar
- endif
- endif
- 130 continue
-c
-c triangulation du triangle de barycentre nbsomm
-c protection a ne pas modifier sinon erreur!
- call tr3str( nbsomm, nt,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % noarst,
- % nosotr, ierr )
- if( ierr .ne. 0 ) then
- write(imprim,*)
- % 'teamqs: erreur irrecuperable en sortie tr3str'
- goto 9999
- endif
- 140 continue
-c
- nbst8 = nbst8 + 1
-c
-c les aretes chainees de la boule sont rendues delaunay
- goto 300
-c
- endif
-c
-c nbtrcf est compris entre 5 et 7 => barycentrage simple
-c ======================================================
-c les 2 coordonnees du barycentre des sommets des aretes
-c simples de la boule du sommet ns
- 200 xbar = xbar / nbstbo
- ybar = ybar / nbstbo
-c
-C DEBUT AJOUT 21/MAI/2005
-C PONDERATION POUR EVITER LES DEGENERESCENSES AVEC PROTECTION
-C SI UN TRIANGLE DE SOMMET NS A UNE AIRE NEGATIVE APRES BARYCENTRAGE
-C ALORS LE SOMMET NS N'EST PAS BOUGE
-c
-c protection des XY du point initial
- xxx = pxyd(1,ns)
- yyy = pxyd(2,ns)
-c
- pxyd(1,ns) = ponde1 * pxyd(1,ns) + ponder * xbar
- pxyd(2,ns) = ponde1 * pxyd(2,ns) + ponder * ybar
-c
-ccc write(imprim,*)'teamqs 200: ns=',ns,' ancien =',xxx,yyy
-ccc write(imprim,*)'teamqs 200: ns=',ns,' nouveau=',pxyd(1,ns),pxyd(2,ns)
-c
- do 240 i=1,nbtrcf
-c le numero de l'arete du triangle nt ne contenant pas le sommet ns
- nt = notrcf(i)
- do 220 na=1,3
-c le numero de l'arete na dans le tableau nosoar
- noar = abs( noartr(na,nt) )
- if( nosoar(1,noar) .ne. ns .and.
- % nosoar(2,noar) .ne. ns ) then
- if( noartr(na,nt) .ge. 0 ) then
- ns2 = nosoar(1,noar)
- ns3 = nosoar(2,noar)
- else
- ns3 = nosoar(1,noar)
- ns2 = nosoar(2,noar)
- endif
- goto 225
- endif
- 220 continue
-
-c aire signee du triangle nt
- 225 d = surtd2( pxyd(1,ns), pxyd(1,ns2), pxyd(1,ns3) )
- if( d .le. 0d0 ) then
-ccc write(imprim,*),'iter=',iter,
-ccc % ' Barycentrage au point ns=',ns,
-ccc % ' XB=',pxyd(1,ns),' YB=',pxyd(2,ns),
-ccc % ' => triangle avec AIRE<0 => Pt REMIS en X =',xxx,
-ccc % ' Y =',yyy
- pxyd(1,ns) = xxx
- pxyd(2,ns) = yyy
- goto 1000
- endif
- 240 continue
-C
-C FIN AJOUT 21/MAI/2005
-c
-c les aretes chainees de la boule sont rendues delaunay
- 300 call tedela( pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar, noar0,
- % moartr, mxartr, n1artr, noartr, modifs )
-c
- 1000 continue
-c
-ccc write(imprim,11000) iter, nbitaq, nbst4, nbst5, nbst8
-ccc11000 format( 'teamqs iter=',i2,' max iter=',i2,':',
-ccc % i7,' sommets de 4t',
-ccc % i7,' sommets 5t+5t',
-ccc % i7,' sommets >7t' )
-c
-c mise a jour pour ne pas oublier les nouveaux sommets
- if( nbs1 .gt. nbs2 ) then
- nbs1 = nbsomm
- nbs2 = nbarpi + 1
- else
- nbs1 = nbarpi + 1
- nbs2 = nbsomm
- endif
-c
- 5000 continue
-c
- 9999 return
- end
-
-
- subroutine teamqt( nutysu,
- % noarst, mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxarcf, notrcf, nostbo,
- % n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
- % ierr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but : amelioration de la qualite de la triangulation
-c -----
-c
-c entrees:
-c --------
-c nutysu : numero de traitement de areteideale() selon le type de surface
-c 0 pas d'emploi de la fonction areteideale() => aretmx active
-c 1 il existe une fonction areteideale()
-c dont seules les 2 premieres composantes de uv sont actives
-c autres options a definir...
-c noarst : noarst(i) numero d'une arete de sommet i
-c mosoar : nombre maximal d'entiers par arete et
-c indice dans nosoar de l'arete suivante dans le hachage
-c mxsoar : nombre maximal d'aretes frontalieres declarables
-c n1soar : numero de la premiere arete vide dans le tableau nosoar
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c mxartr : nombre maximal de triangles declarables dans noartr
-c n1artr : numero du premier triangle vide dans le tableau noartr
-c le chainage des triangles vides se fait sur noartr(2,.)
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxarcf : nombre maximal de triangles empilables
-c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : tableau du numero de sommet dans sa ligne pour chaque
-c sommet frontalier
-c numero du point dans le lexique point si interne impose
-c 0 si le point est interne non impose par l'utilisateur
-c -1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
-c
-c modifies :
-c ----------
-c nbsomm : nombre actuel de sommets de la triangulation
-c (certains sommets internes ont ete desactives ou ajoutes)
-c pxyd : tableau des coordonnees 2d des points
-c
-c auxiliaires:
-c ------------
-c notrcf : tableau ( mxarcf ) auxiliaire d'entiers
-c numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxarcf ) auxiliaire d'entiers
-c numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
-c larmin : tableau ( mxarcf ) auxiliaire d'entiers
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc juin 1997
-c....................................................................012
- common / unites / lecteu, imprim, nunite(30)
- double precision pxyd(3,*), d2d3(3,3)
- integer noartr(moartr,*),
- % nosoar(mosoar,*),
- % noarst(*),
- % notrcf(mxarcf),
- % nslign(*),
- % nostbo(mxarcf),
- % n1arcf(0:mxarcf),
- % noarcf(3,mxarcf),
- % larmin(mxarcf)
- double precision comxmi(3,2)
-c
-c suppression des sommets de triangles equilateraux trop proches
-c d'un sommet frontalier ou d'un point interne impose par
-c triangulation frontale de l'etoile et mise en delaunay
-c ==============================================================
- call tesusp( nbarpi, pxyd, noarst,
- % mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxarcf, n1arcf, noarcf, larmin, notrcf, nostbo,
- % ierr )
- if( ierr .ne. 0 ) goto 9999
-c
-c ajustage des tailles moyennes des aretes avec ampli=1.34d0 entre
-c ampli/2 x taille_souhaitee et ampli x taille_souhaitee
-c + barycentrage des sommets et mise en triangulation delaunay
-c ================================================================
- call teamqa( nutysu,
- % noarst, mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxarcf, notrcf, nostbo,
- % n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
- % ierr )
- if( ierr .ne. 0 ) goto 9999
-c
-cccc modification de la topologie autour des sommets frontaliers
-cccc pour avoir un nombre de triangles egal a l'angle/60 degres
-cccc et mise en triangulation delaunay locale
-cccc ===========================================================
-ccc call teamsf( nutysu,
-ccc % noarst, mosoar, mxsoar, n1soar, nosoar,
-ccc % moartr, mxartr, n1artr, noartr,
-ccc % mxarcf, notrcf, nostbo,
-ccc % n1arcf, noarcf, larmin,
-ccc % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-ccc % ierr )
-ccc if( ierr .ne. 0 ) goto 9999
-c
-c quelques iterations de barycentrage des points internes
-c modification de la topologie pour avoir 4 ou 5 ou 6 triangles
-c pour chaque sommet de la triangulation
-c et mise en triangulation delaunay
-c =============================================================
- call teamqs( nutysu,
- % noarst, mosoar, mxsoar, n1soar, nosoar,
- % moartr, mxartr, n1artr, noartr,
- % mxarcf, notrcf, nostbo,
- % n1arcf, noarcf, larmin,
- % comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
- % ierr )
-c
- 9999 return
- end
-
- subroutine trfrcf( nscent, mosoar, nosoar, moartr, noartr,
- % nbtrcf, notrcf, nbarfr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but : calculer le nombre d'aretes simples du contour ferme des
-c ----- nbtrcf triangles de numeros stockes dans le tableau notrcf
-c ayant tous le sommet nscent
-c
-c entrees:
-c --------
-c nscent : numero du sommet appartenant a tous les triangles notrcf
-c mosoar : nombre maximal d'entiers par arete et
-c indice dans nosoar de l'arete suivante dans le hachage
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c nbtrcf : >0 nombre de triangles empiles
-c =0 si impossible de tourner autour du point
-c =-nbtrcf si apres butee sur la frontiere il y a a nouveau
-c butee sur la frontiere . a ce stade on ne peut dire si tous
-c les triangles ayant ce sommet ont ete recenses
-c ce cas arrive seulement si le sommet est sur la frontiere
-c notrcf : numero dans noartr des triangles de sommet ns
-c
-c sortie :
-c --------
-c nbarfr : nombre d'aretes simples frontalieres
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc juin 1997
-c....................................................................012
- integer noartr(moartr,*),
- % nosoar(mosoar,*),
- % notrcf(1:nbtrcf)
+c sortie :
+c --------
+c nbarfr : nombre d'aretes simples frontalieres
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : alain perronnet analyse numerique paris upmc juin 1997
+c....................................................................012
+ integer noartr(moartr,*),
+ % nosoar(mosoar,*),
+ % notrcf(1:nbtrcf)
c
nbarfr = 0
do 50 n=1,nbtrcf
end
- subroutine tridcf( nbcf0, pxyd, noarst,
+ subroutine tridcf( nbcf0, nbstpe, nostpe, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf, larmin,
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : triangulation directe de nbcf0 contours fermes (cf)
c ----- definis par la liste circulaire de leurs aretes peripheriques
+c avec integration de nbstpe sommets isoles a l'un des cf initiaux
c
c entrees:
c --------
c nbcf0 : nombre initial de cf a trianguler
+c nbstpe : nombre de sommets isoles a l'interieur des cf et
+c a devenir sommets de la triangulation
+c nostpe : numero dans pxyd des nbstpe sommets isoles
c pxyd : tableau des coordonnees 2d des points
c par point : x y distance_souhaitee
c mosoar : nombre maximal d'entiers par arete et
c 3 si contour ferme reduit a moins de 3 aretes
c 4 saturation du tableau notrcf
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c modifs : alain perronnet laboratoire jl lions upmc paris octobre 2006
c....................................................................012
common / unites / lecteu, imprim, nunite(30)
double precision pxyd(3,*)
- integer noartr(moartr,*),
+ integer nostpe(nbstpe),
+ % noartr(moartr,*),
% nosoar(mosoar,mxsoar),
% noarst(*),
% n1arcf(0:mxarcf),
% larmin(mxarcf),
% notrcf(mxarcf)
c
-ccc integer nosotr(3)
-ccc double precision d, surtd2
+ integer nosotr(3)
+ double precision d, diptdr, surtd2, dmin, s
+c
+c depart avec nbcf0 cf a trianguler
+ nbcf = nbcf0
+c
+c le nombre de triangles formes dans l'ensemble des cf
+ nbtrcf = 0
+c
+c le nombre restant de sommets isoles a integrer au cf
+ nbstp = nbstpe
+c
+ 1 if( nbstp .le. 0 ) goto 10
+c
+c il existe au moins un sommet isole
+c recherche d'un cf dont la premiere arete forme un triangle
+c d'aire>0 avec un sommet isole et recherche du sommet isole
+c le plus proche de cette arete
+c ==========================================================
+ imin = 0
+ dmin = 1d123
+ do 6 ncf=1,nbcf
+c le cf en haut de pile a pour arete avant la premiere arete
+ na1 = n1arcf( ncf )
+ na2 = na1
+c recherche de l'arete qui precede la premiere arete
+ 2 if( noarcf( 2, na2 ) .ne. na1 ) then
+ na2 = noarcf( 2, na2 )
+ goto 2
+ endif
+c l'arete na0 dans noarcf qui precede n1arcf( ncf )
+ na0 = na2
+c la premiere arete du cf
+ na1 = noarcf( 2, na0 )
+c son numero dans nosoar
+ noar1 = noarcf( 3, na1 )
+c l'arete suivante
+ na2 = noarcf( 2, na1 )
+c le no pxyd des 2 sommets de l'arete na1
+ ns1 = noarcf( 1, na1 )
+ ns2 = noarcf( 1, na2 )
+ do 3 i=1,nbstpe
+c le sommet isole ns3
+ ns3 = nostpe( i )
+ if( ns3 .le. 0 ) goto 3
+c aire du triangle arete na1 et sommet ns3
+ d = surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+ if( d .gt. 0d0 ) then
+c distance de ce sommet ns3 a l'arete na1
+ d = diptdr( pxyd(1,ns3), pxyd(1,ns1), pxyd(1,ns2) )
+ if( d .lt. dmin ) then
+ dmin = d
+ imin = i
+ endif
+ endif
+ 3 continue
+ if( imin .gt. 0 ) then
+c le sommet imin de nostpe est a distance minimale de
+c la premiere arete du cf de numero ncf
+c la formation de l'arete ns2-ns3 dans le tableau nosoar
+ call fasoar( ns2, ns3, -1, -1, 0,
+ % mosoar, mxsoar, n1soar, nosoar, noarst,
+ % noar2, ierr )
+ if( ierr .ne. 0 ) goto 9900
+c la formation de l'arete ns3-ns1 dans le tableau nosoar
+ call fasoar( ns3, ns1, -1, -1, 0,
+ % mosoar, mxsoar, n1soar, nosoar, noarst,
+ % noar3, ierr )
+ if( ierr .ne. 0 ) goto 9900
+c
+c ajout dans noartr du triangle de sommets ns1 ns2 ns3
+c et d'aretes na1, noar2, noar3 dans nosoar
+ call trcf3a( ns1, ns2, ns3,
+ % noar1, noar2, noar3,
+ % mosoar, nosoar,
+ % moartr, n1artr, noartr,
+ % nt )
+ s = surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+ if( s .le. 0 ) then
+ write(imprim,*)'tridcf: trcf3a produit tr',nt,' st',
+ % ns1,ns2,ns3
+ write(imprim,*)'tridcf: triangle AIRE<0'
+ endif
+ if( nt .le. 0 ) then
+ ierr = 7
+ return
+ endif
+ if( nbtrcf .ge. mxarcf ) then
+ write(imprim,*) 'saturation du tableau notrcf'
+ ierr = 8
+ return
+ endif
+ nbtrcf = nbtrcf + 1
+ notrcf( nbtrcf ) = nt
+c
+c modification du cf. creation d'une arete dans noarcf
+ na12 = n1arcf(0)
+ if( na12 .le. 0 ) then
+ write(imprim,*) 'saturation du tableau noarcf'
+ ierr = 10
+ return
+ endif
+c la 1-ere arete vide de noarcf est mise a jour
+ n1arcf(0) = noarcf( 2, na12 )
+c
+c l'arete suivante de na0
+ noarcf( 1, na1 ) = ns1
+ noarcf( 2, na1 ) = na12
+ noarcf( 3, na1 ) = noar3
+c l'arete suivante de na1
+ noarcf( 1, na12 ) = ns3
+ noarcf( 2, na12 ) = na2
+ noarcf( 3, na12 ) = noar2
+c
+c un sommet isole traite
+ nbstp = nbstp - 1
+ nostpe( imin ) = - nostpe( imin )
+ goto 1
+ endif
c
-c depart avec nbcf0 cf a trianguler
- nbcf = nbcf0
+ 6 continue
c
-c le nombre de triangles formes dans l'ensemble des cf
- nbtrcf = 0
+ if( imin .eq. 0 ) then
+ write(imprim,*) 'tridcf: il reste',nbstp,
+ % ' sommets isoles non triangules'
+ write(imprim,*) 'ameliorer l''algorithme'
+ccc pause
+ ierr = 9
+ return
+ endif
c
c tant qu'il existe un cf a trianguler faire
c la triangulation directe du cf
ierr = 2
return
endif
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr)
+ s = surtd2( pxyd(1,nosotr(1)),
+ % pxyd(1,nosotr(2)),
+ % pxyd(1,nosotr(3)) )
+ if( s .le. 0 ) then
+ write(imprim,*)'tridcf: trcf3s produit tr',nt,' st',nosotr
+ write(imprim,*)'tridcf: triangle AIRE<0'
+ endif
c
c ajout du triangle cree a sa pile
if( nbtrcf .ge. mxarcf ) then
c le numero du triangle ajoute dans le tableau noartr
nt0 = notrcf( ntp0 )
c
-cccc aire signee du triangle nt0
-cccc le numero des 3 sommets du triangle nt
-ccc call nusotr( nt0, mosoar, nosoar, moartr, noartr,
-ccc % nosotr )
-ccc d = surtd2( pxyd(1,nosotr(1)), pxyd(1,nosotr(2)),
-ccc % pxyd(1,nosotr(3)) )
-ccc if( d .le. 0 ) then
-cccc
-cccc un triangle d'aire negative de plus
-ccc write(imprim,*) 'triangle ',nt0,' st:',nosotr,
-ccc % ' d aire ',d,'<=0'
-ccc pause
-ccc endif
-c
-cccc trace du triangle nt0
-ccc call mttrtr( pxyd, nt0, moartr, noartr, mosoar, nosoar,
-ccc % ncturq, ncblan )
-c
-c boucle sur les 3 aretes du triangle
+c boucle sur les 3 aretes du triangle nt0
do 20 i=1,3
c
c le numero de l'arete i du triangle dans le tableau nosoar
c l'arete appartient a 2 triangles differents de nt0
c anomalie. chainage des triangles des aretes defectueux
c a corriger
- write(imprim,*) 'pause dans tridcf'
+ write(imprim,*) 'tridcf: erreur 1 arete dans 3 triangles'
+ write(imprim,*) 'tridcf: arete nosoar(',noar,')=',
+ % (nosoar(k,noar),k=1,mosoar)
+ call nusotr( nt0, mosoar, nosoar, moartr, noartr, nosotr)
+ write(imprim,*) 'tridcf: triangle nt0=',nt0,' st:',
+ % (nosotr(k),k=1,3)
+ call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr)
+ write(imprim,*) 'tridcf: triangle nt1=',nt1,' st:',
+ % (nosotr(k),k=1,3)
+ call nusotr( nt2, mosoar, nosoar, moartr, noartr, nosotr)
+ write(imprim,*) 'tridcf: triangle nt2=',nt2,' st:',
+ % (nosotr(k),k=1,3)
+ccc pause
ierr = 5
return
endif
20 continue
c
30 continue
+ return
+c
+c erreur tableau nosoar sature
+ 9900 write(imprim,*) 'saturation du tableau nosoar'
+ ierr = 6
+ return
end
-
- subroutine te1stm( nsasup, pxyd, noarst,
+ subroutine te1stm( nsasup, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf, larmin, notrcf, liarcf,
c entrees:
c --------
c nsasup : numero dans le tableau pxyd du sommet a supprimer
+c nbarpi : numero du dernier sommet frontalier ou interne impose
c pxyd : tableau des coordonnees 2d des points
c par point : x y distance_souhaitee
c mosoar : nombre maximal d'entiers par arete et
c >0 si une erreur est survenue
c =11 algorithme defaillant
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc mars 2006
+c auteur : alain perronnet analyse numerique paris upmc mars 1997
c....................................................................012
- parameter ( lchain=6, quamal=0.3)
+ parameter ( lchain=6, mxstpe=512)
common / unites / lecteu,imprim,intera,nunite(29)
- double precision pxyd(3,*)
+ double precision pxyd(3,*), s0, s1, surtd2, s
integer nosoar(mosoar,mxsoar),
- % noartr(moartr,*),
+ % noartr(moartr,mxartr),
% noarst(*),
% n1arcf(0:mxarcf),
% noarcf(3,mxarcf),
% larmin(mxarcf),
% notrcf(mxarcf),
- % liarcf(mxarcf)
+ % liarcf(mxarcf),
+ % nostpe(mxstpe),
+ % nosotr(3)
+c
+ if( nsasup .le. nbarpi ) then
+c sommet frontalier non destructible
+ ierr = -1
+ return
+ endif
+ ierr = 0
c
c nsasup est il un sommet interne, "centre" d'une boule de triangles?
c => le sommet nsasup peut etre supprime
c ===================================================================
c formation du cf de ''centre'' le sommet nsasup
call trp1st( nsasup, noarst, mosoar, nosoar,
- % moartr, noartr,
+ % moartr, mxartr, noartr,
% mxarcf, nbtrcf, notrcf )
- if( nbtrcf .le. 0 ) then
+c
+ if( nbtrcf .le. 2 ) then
c erreur: impossible de trouver tous les triangles de sommet nsasup
+c ou pas assez de triangles de sommet nsasup
c le sommet nsasup n'est pas supprime de la triangulation
ierr = -1
return
- else if( nbtrcf .le. 2 ) then
-c le sommet nsasup n'est pas supprime
- ierr = -1
- return
endif
+c
if( nbtrcf*3 .gt. mxarcf ) then
write(imprim,*) 'saturation du tableau noarcf'
ierr = 10
return
endif
c
-ccc trace des triangles de l'etoile du sommet nsasup
-ccc call trpltr( nbtrcf, notrcf, pxyd,
-ccc % moartr, noartr, mosoar, nosoar,
-ccc % ncroug, ncblan )
-c
c si toutes les aretes du cf sont frontalieres, alors il est
c interdit de detruire le sommet "centre" du cf
c calcul du nombre nbarfr des aretes simples des nbtrcf triangles
call trfrcf( nsasup, mosoar, nosoar, moartr, noartr,
- % nbtrcf, notrcf, nbarfr )
+ % nbtrcf, notrcf, nbarfr )
if( nbarfr .ge. nbtrcf ) then
c toutes les aretes simples sont frontalieres
c le sommet nsasup ("centre" de la cavite) n'est pas supprime
return
endif
c
+c calcul des surfaces avant suppression du point
+ s0 = 0d0
+ do 10 i=1,nbtrcf
+ nt = notrcf(i)
+c les numeros des 3 sommets du triangle nt
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+ s = surtd2( pxyd(1,nosotr(1)),
+ % pxyd(1,nosotr(2)),
+ % pxyd(1,nosotr(3)) )
+ s0 = s0 + abs( s )
+ 10 continue
+c
c formation du contour ferme (liste chainee des aretes simples)
c forme a partir des aretes des triangles de l'etoile du sommet nsasup
- call focftr( nbtrcf, notrcf, pxyd, noarst,
+c les aretes doubles sont detruites
+c les triangles du cf sont detruits
+ call focftr( nbtrcf, notrcf, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
- % nbarcf, n1arcf, noarcf,
+ % nbarcf, n1arcf, noarcf, nbstpe, nostpe,
% ierr )
if( ierr .ne. 0 ) then
c modification de ierr pour continuer le calcul
return
endif
c
-c ici le sommet nsasup appartient a aucune arete
+c ici le sommet nsasup n'appartient plus a aucune arete
noarst( nsasup ) = 0
c
c chainage des aretes vides dans le tableau noarcf
c triangulation directe du contour ferme sans le sommet nsasup
c ============================================================
nbcf = 1
- call tridcf( nbcf, pxyd, noarst,
+ call tridcf( nbcf, nbstpe, nostpe, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf, larmin,
% nbtrcf, notrcf, ierr )
if( ierr .ne. 0 ) return
+c calcul des surfaces apres suppression du point
+ s1 = 0d0
+ do 55 i=1,nbtrcf
+ nt = notrcf(i)
+c les numeros des 3 sommets du triangle nt
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+ s = surtd2( pxyd(1,nosotr(1)),
+ % pxyd(1,nosotr(2)),
+ % pxyd(1,nosotr(3)) )
+ if( s .le. 0 ) then
+ write(imprim,*)'te1stm: apres tridcf le triangle',nt,
+ % ' st',nosotr,' AIRE<0'
+ endif
+ s1 = s1 + abs( s )
+ 55 continue
+c
+ if( abs(s0-s1) .gt. 1d-10*s0 ) then
+ write(imprim,*)
+ write(imprim,*)'te1stm: difference des aires lors suppression st',
+ % nsasup
+ write(imprim,10055) s0, s1
+10055 format('aire0=',d25.16,' aire1=',d25.16)
+ endif
c
c transformation des triangles du cf en triangles delaunay
c ========================================================
call tedela( pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar, liarcf(1),
% moartr, mxartr, n1artr, noartr, modifs )
-ccc write(imprim,*) 'nombre echanges diagonales =',modifs
return
end
subroutine tr3str( np, nt,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
- % noarst,
- % nutr, ierr )
+ % noarst, nutr, ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : former les 3 sous-triangles du triangle nt a partir
c ----- du point interne np
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc avril 1997
c....................................................................012
+ common / unites / lecteu,imprim,intera,nunite(29)
integer nosoar(mosoar,*),
% noartr(moartr,*),
% noarst(*)
if( abs(noartr(n1,nt1)) .eq. noaret ) goto 15
10 continue
c impossible d'arriver ici sans bogue!
- write(imprim,*) 'pause dans te2t2t 1'
+ write(imprim,*) 'anomalie dans te2t2t 1'
c
c l'arete de sommets 2 et 3
15 if( n1 .lt. 3 ) then
if( abs(noartr(n1,nt2)) .eq. noaret ) goto 25
20 continue
c impossible d'arriver ici sans bogue!
- write(imprim,*) 'pause dans te2t2t 2'
+ write(imprim,*) 'Anomalie dans te2t2t 2'
c
c l'arete de sommets 1 et 4
25 if( n1 .lt. 3 ) then
endif
c
c suppression de l'arete noaret
- call sasoar( noaret, mosoar, mxsoar, n1soar, nosoar )
+ call sasoar( noaret, mosoar, mxsoar, n1soar, nosoar, noarst )
c
c nt1 = triangle 143
noartr(1,nt1) = na14
end
-
subroutine f0trte( letree, pxyd,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc mars 1997
c....................................................................012
- common / unites / lecteu, imprim, nunite(30)
double precision pxyd(3,*)
integer letree(0:8),
% milieu(3),
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc juillet 1995
c2345x7..............................................................012
+ common / unites / lecteu, imprim, nunite(30)
integer noartr(moartr,*), nosoar(mosoar,*)
c
c le numero de triangle est il correct ?
ns3 = nosoar(1,-na)
endif
end
+
subroutine trpite( letree, pxyd,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, mxartr, n1artr, noartr,
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c auteur : alain perronnet analyse numerique paris upmc mars 1997
c....................................................................012
- logical tratri
- common / dv2dco / tratri
-c trace ou non des triangles generes dans la triangulation
common / unites / lecteu, imprim, nunite(30)
double precision pxyd(3,*)
integer letree(0:8),
c
integer nosotr(3)
c
-c si pas de point interne alors trace eventuel puis retour
+ ierr = 0
+c
+c si pas de point interne alors retour
if( letree(0) .eq. 0 ) goto 150
c
c il existe au moins un point interne a trianguler
10010 format(' erreur trpite: pas de triangle contenant le point',i7)
c
150 continue
-
-ccc 150 if( tratri ) then
-cccc les traces sont demandes
-ccc call efface
-cccc le cadre objet global en unites utilisateur
-ccc xx1 = min(pxyd(1,nosotr(1)),pxyd(1,nosotr(2)),pxyd(1,nosotr(3)))
-ccc xx2 = max(pxyd(1,nosotr(1)),pxyd(1,nosotr(2)),pxyd(1,nosotr(3)))
-ccc yy1 = min(pxyd(2,nosotr(1)),pxyd(2,nosotr(2)),pxyd(2,nosotr(3)))
-ccc yy2 = max(pxyd(2,nosotr(1)),pxyd(2,nosotr(2)),pxyd(2,nosotr(3)))
-ccc if( xx1 .ge. xx2 ) xx2 = xx1 + (yy2-yy1)
-ccc if( yy1 .ge. yy2 ) yy2 = yy1 + (xx2-xx1)*0.5
-ccc call isofenetre( xx1-(xx2-xx1), xx2+(xx2-xx1),
-ccc % yy1-(yy2-yy1), yy2+(yy2-yy1) )
-ccc do 200 i=1,nbtr
-cccc trace du triangle nutr(i)
-ccc call mttrtr( pxyd, nutr(i), moartr, noartr, mosoar, nosoar,
-ccc % i, ncblan )
-ccc 200 continue
-ccc endif
-
end
- subroutine sasoar( noar, mosoar, mxsoar, n1soar, nosoar )
+ subroutine sasoar( noar, mosoar, mxsoar, n1soar, nosoar, noarst )
c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : supprimer l'arete noar du tableau nosoar
-c ----- si celle ci n'est pas une arete des lignes de la frontiere
+c ----- si celle ci n'est pas une arete des lignes de la fontiere
c
c la methode employee ici est celle du hachage
c avec pour fonction d'adressage h = min( nu2sar(1), nu2sar(2) )
c une arete i de nosoar est vide <=> nosoar(1,i)=0 et
c nosoar(4,arete vide)=l'arete vide qui precede
c nosoar(5,arete vide)=l'arete vide qui suit
+c noarst : numero d'une arete de nosoar pour chaque sommet
c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique upmc paris mars 1997
+c auteur : alain perronnet analyse numerique upmc paris mars 1997
+c modifs : alain perronnet laboratoire jl lions upmc paris octobre 2006
c ...................................................................012
common / unites / lecteu, imprim, nunite(30)
- integer nosoar(mosoar,mxsoar)
+ integer nosoar(mosoar,mxsoar), noarst(*), ns(2)
+c
+c 13/10/2006
+c mise a jour de noarst pour les 2 sommets de l'arete a supprimer
+c necessaire uniquement pour les sommets frontaliers et internes imposes
+c le numero des 2 sommets de l'arete noar a supprimer
+ ns(1) = nosoar(1,noar)
+ ns(2) = nosoar(2,noar)
+ do 8 k=1,2
+ if( noarst(ns(k)) .eq. noar ) then
+c il faut remettre a jour le pointeur sur une arete
+ if(nosoar(1,ns(k)).eq.ns(k) .and. nosoar(2,ns(k)).gt.0
+ % .and. nosoar(4,ns(k)) .gt. 0 ) then
+c arete active de sommet ns(k)
+ noarst( ns(k) ) = ns(k)
+ else
+ do 5 i=1,mxsoar
+ if( nosoar(1,i).gt.0 .and. nosoar(4,i).gt.0 ) then
+c arete non vide
+ if( nosoar(2,i).eq.ns(k) .or.
+ % (nosoar(1,i).eq.ns(k).and.nosoar(2,i).gt.0))then
+c arete active de sommet ns(k)
+ noarst( ns(k) ) = i
+ goto 8
+ endif
+ endif
+ 5 continue
+ endif
+ endif
+ 8 continue
+c 13/10/2006
c
if( nosoar(3,noar) .le. 0 ) then
c
% ' st2=',nosoar(2,noar),' ligne=',nosoar(3,noar),
% ' tr1=',nosoar(4,noar),' tr2=',nosoar(5,noar)
write(imprim,*) 'chainages=',(nosoar(i,noar),i=6,mosoar)
+ccc pause
c l'arete n'est pas detruite
return
c
end
- subroutine caetoi( noar, mosoar, mxsoar, n1soar, nosoar,
+ subroutine caetoi( noar, mosoar, mxsoar, n1soar, nosoar, noarst,
% n1aeoc, nbtrar )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : ajouter (ou retirer) l'arete noar de nosoar de l'etoile
c2345x7..............................................................012
parameter (lchain=6)
common / unites / lecteu, imprim, nunite(30)
- integer nosoar(mosoar,mxsoar)
+ integer nosoar(mosoar,mxsoar), noarst(*)
c
c si l'arete n'appartient pas aux aretes de l'etoile naetoi
c alors elle est ajoutee a l'etoile dans naetoi
return
endif
nbpass = nbpass + 1
- if( nbpass .gt. 128 ) then
+ if( nbpass .gt. 512 ) then
write(imprim,*)'Pb dans caetoi: boucle infinie evitee'
nbtrar = 0
return
nosoar( lchain, noar ) = -1
c
c destruction du tableau nosoar de l'arete double noar
- call sasoar( noar, mosoar, mxsoar, n1soar, nosoar )
+ call sasoar( noar, mosoar, mxsoar, n1soar, nosoar, noarst )
c
c arete double
nbtrar = 2
end
- subroutine focftr( nbtrcf, notrcf, pxyd, noarst,
+ subroutine focftr( nbtrcf, notrcf, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
- % nbarcf, n1arcf, noarcf,
+ % nbarcf, n1arcf, noarcf, nbstpe, nostpe,
% ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c but : former un contour ferme (cf) avec les aretes simples des
c --------
c nbtrcf : nombre de triangles du cf a former
c notrcf : numero des triangles dans le tableau noartr
+c nbarpi : numero du dernier sommet frontalier ou interne impose
c pxyd : tableau des coordonnees 2d des points
c par point : x y distance_souhaitee
c
c noarcf : numero des aretes de la ligne du contour ferme
c attention: chainage circulaire des aretes
c les aretes vides pointes par n1arcf(0) ne sont pas chainees
+c nbstpe : nombre de sommets perdus dans la suppression des triangles
+c nostpe : numero des sommets perdus dans la suppression des triangles
c ierr : 0 si pas d'erreur
c 14 si les lignes fermees se coupent => donnees a revoir
c 15 si une seule arete simple frontaliere
c de la boule sont frontalieres!
c 17 si boucle infinie dans caetoi
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c auteur : alain perronnet analyse numerique upmc paris mars 1997
+c modifs : alain perronnet laboratoire jl lions upmc paris octobre 2006
c....................................................................012
- parameter (lchain=6)
+ parameter (lchain=6, mxstpe=512)
common / unites / lecteu, imprim, nunite(30)
double precision pxyd(3,*)
integer notrcf(1:nbtrcf)
% noartr(moartr,*),
% n1arcf(0:*),
% noarcf(3,*),
- % noarst(*)
+ % noarst(*),
+ % nostpe(mxstpe),
+ % nosotr(3)
c
c formation des aretes simples du cf autour de l'arete ns1-ns2
c attention: le chainage lchain du tableau nosoar devient actif
c ce qui equivaut a dire que l'etoile des aretes simples est vide
c (initialisation dans le sp insoar puis remise a -1 dans la suite!)
n1aeoc = 0
+ ierr = 0
+c
+c 13/10/2006
+c nombre de sommets des triangles a supprimer sans repetition
+ nbst = 0
+c 13/10/2006
c
c ajout a l'etoile des aretes simples des 3 aretes des triangles a supprimer
c suppression des triangles de l'etoile pour les aretes simples de l'etoile
do 10 i=1,nbtrcf
+c
c ajout ou retrait des 3 aretes du triangle notrcf(i) de l'etoile
nt = notrcf( i )
+c
+c 13/10/2006 ...............................................
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+c
+c ajout des numeros de sommets non encore vus dans l'etoile
+ do 3 k=1,3
+ do 2 j=1,nbst
+ if( nosotr(k) .eq. nostpe(j) ) goto 3
+ 2 continue
+c ajout du sommet
+ nbst = nbst + 1
+ nostpe( nbst ) = nosotr(k)
+ 3 continue
+c 13/10/2006 ................................................
+c
do 5 j=1,3
c l'arete de nosoar a traiter
noar = abs( noartr(j,nt) )
- call caetoi( noar, mosoar, mxsoar, n1soar, nosoar,
+ call caetoi( noar, mosoar, mxsoar, n1soar, nosoar, noarst,
% n1aeoc, nbtrar )
if( nbtrar .le. 0 ) then
+ write(imprim,*)'focftr: erreur dans caetoi noar=',noar
ierr = 17
return
endif
if( nbtrar .eq. 1 ) then
if( nosoar(4,noar) .eq. nt ) then
nosoar(4,noar) = nosoar(5,noar)
+ else if( nosoar(5,noar) .eq. nt ) then
+ nosoar(5,noar) = -1
+ else
+ write(imprim,*)'focftr: anomalie arete',noar,
+ % ' sans triangle',nt
+ write(imprim,*)'focftr: nosoar(',noar,')=',
+ % (nosoar(kk,noar),kk=1,mosoar)
+ nosoar(5,noar) = -1
endif
- nosoar(5,noar) = -1
c else
c l'arete appartient a aucun triangle => elle est vide
c les positions 4 et 5 servent maintenant aux chainages des vides
c attention: boucle infinie si toutes les aretes simples
c de la boule sont frontalieres!... arretee par ce test
ierr = 16
+ write(imprim,*)'focftr: boucle dans les aretes de l etoile'
return
endif
noar = n1aeoc
if( na0 .le. 0 ) then
c une seule arete simple frontaliere
ierr = 15
+ write(imprim,*)'focftr: 1 arete seule pour l etoile'
return
endif
c le suivant de l'ancien dernier est l'ancien premier
c mise a jour du numero d'arete du sommet ns0
noarst(ns0) = na1
c
-cccc trace de l'arete
-ccc call dvtrar( pxyd, ns0, ns1, ncvert, ncblan )
-c
c l'arete suivante a chainer
n1aeoc = nosoar( lchain, na1 )
c l'arete na1 n'est plus dans l'etoile
c mise a jour du numero d'arete du sommet ns1
noarst(ns1) = na1
c
-cccc trace de l'arete
-ccc call dvtrar( pxyd, ns1, ns2, ncvert, ncblan )
-c
c suppression de l'arete des aretes simples de l'etoile
if( n1aeoc .eq. na1 ) then
n1aeoc = nosoar( lchain, na1 )
c verification
if( ns1 .ne. ns0 ) then
c arete non retrouvee : l'etoile ne se referme pas
-c nblgrc(nrerr) = 3
-c kerr(1) = 'focftr: revoyez vos donnees'
-c kerr(2) = 'les lignes fermees doivent etre disjointes'
-c kerr(3) = 'verifiez si elles ne se coupent pas'
-c call lereur
- write(imprim,*) 'focftr: revoyez vos donnees'
- write(imprim,*)'les lignes fermees doivent etre disjointes'
- write(imprim,*)'verifiez si elles ne se coupent pas'
+ write(imprim,*)'focftr: revoyez vos donnees du bord'
+ write(imprim,*)'les lignes fermees doivent etre disjointes'
+ write(imprim,*)'verifiez si elles ne se coupent pas'
ierr = 14
return
endif
c => realisation d'un chainage circulaire des aretes du cf
noarcf( 2, nbarcf ) = 1
c
+c 13/10/2006
+c existe t il des sommets perdus?
+c -------------------------------
+ if( nbst .gt. mxstpe ) then
+ write(imprim,*)'focftr: tableau nostfe(',mxstpe,') a augmenter'
+ ierr = 15
+ return
+ endif
+c le nombre de sommets perdus
+ nbstpe = nbst - nbarcf
+ if( nbstpe .gt. 0 ) then
+c oui: stockage dans nostpe des sommets perdus
+c tout sommet des aretes de l'etoile est supprime
+c de la liste des sommets
+ do 40 i=1,nbarcf
+c le numero du sommet de l'arete du cf
+ ns1 = noarcf( 1, i )
+ do 30 j=1,nbst
+ if( ns1 .eq. nostpe(j) ) then
+c le sommet peripherique est supprime
+c de la liste des sommets perdus
+ nostpe(j) = 0
+ goto 40
+ endif
+ 30 continue
+ 40 continue
+c
+c compression
+ n = 0
+ do 45 i=1,nbst
+ if( nostpe(i) .eq. 0 .or. nostpe(i) .gt. nbarpi ) then
+c un sommet de l'etoile ou perdu mais supprimable
+c ce qui apporte plus de qualites aux triangles a former
+ n = n + 1
+ else
+c un sommet perdu
+ nostpe(i-n) = nostpe(i)
+ endif
+ 45 continue
+ nbstpe = nbst - n
+ccc write(imprim,*)'focftr:',nbstpe,' sommets isoles:',(nostpe(k),k=1,nbstpe)
+ endif
+c 13/10/2006
+c
c destruction des triangles de l'etoile du tableau noartr
c -------------------------------------------------------
- do 50 i=1,nbtrcf
+ do 60 n=1,nbtrcf
c le numero du triangle dans noartr
- nt0 = notrcf( i )
+ nt0 = notrcf( n )
c l'arete 1 de nt0 devient nulle
noartr( 1, nt0 ) = 0
c chainage de nt0 en tete du chainage des triangles vides de noartr
noartr( 2, nt0 ) = n1artr
n1artr = nt0
- 50 continue
+ 60 continue
end
linter = 0
end
-
subroutine tefoar( narete, nbarpi, pxyd,
% mosoar, mxsoar, n1soar, nosoar,
- % moartr, n1artr, noartr, noarst,
+ % moartr, mxartr, n1artr, noartr, noarst,
% mxarcf, n1arcf, noarcf, larmin, notrcf,
% ierr )
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
c attention: mxsoar>3*mxsomm obligatoire!
c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre maximal de triangles stockables dans le tableau noartr
c
c modifies:
c ---------
c a probleme
c 10 un des tableaux n1arcf, noarcf notrcf est sature
c augmenter a l'appel mxarcf
-c 11 algorithme defaillant
+c >11 algorithme defaillant
c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c auteur : alain perronnet analyse numerique paris upmc mars 1997
+c modifs : alain perronnet laboratoire jl lions upmc paris octobre 2006
c....................................................................012
- parameter (mxpitr=32)
+ parameter (mxpitr=32, mxstpe=512)
common / unites / lecteu,imprim,intera,nunite(29)
- logical tratri
- common / dv2dco / tratri
double precision pxyd(3,*)
- integer noartr(moartr,*),
+ integer noartr(moartr,mxartr),
% nosoar(mosoar,mxsoar),
% noarst(*),
% n1arcf(0:mxarcf),
% noarcf(3,mxarcf),
% larmin(mxarcf),
- % notrcf(mxarcf)
+ % notrcf(mxarcf),
+ % nostpe(mxstpe)
c
integer lapitr(mxpitr)
double precision x1,y1,x2,y2,d12,d3,d4,x,y,d,dmin
integer nosotr(3), ns(2)
integer nacf(1:2), nacf1, nacf2
equivalence (nacf(1),nacf1), (nacf(2),nacf2)
+c
+ ierr = 0
c
c traitement de cette arete perdue
ns1 = nosoar( 1, narete )
ns2 = nosoar( 2, narete )
c
- if( tratri ) then
-c les traces sont demandes
-c call efface
-c le cadre objet global en unites utilisateur
- xx1 = min( pxyd(1,ns1), pxyd(1,ns2) )
- xx2 = max( pxyd(1,ns1), pxyd(1,ns2) )
- yy1 = min( pxyd(2,ns1), pxyd(2,ns2) )
- yy2 = max( pxyd(2,ns1), pxyd(2,ns2) )
- if( xx1 .ge. xx2 ) xx2 = xx1 + (yy2-yy1)
- if( yy1 .ge. yy2 ) yy2 = yy1 + (xx2-xx1)*0.5
-c call isofenetre( xx1-(xx2-xx1), xx2+(xx2-xx1),
-c % yy1-(yy2-yy1), yy2+(yy2-yy1) )
- endif
-c
-cccc trace de l'arete perdue
-ccc call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
+ccc write(imprim,*)
+ccc write(imprim,*) 'tefoar reconstruction de l''arete ',ns1,' ', ns2
+ccc write(imprim,*) 'sommet',ns1,' x=',pxyd(1,ns1),' y=',pxyd(2,ns1)
+ccc write(imprim,*) 'sommet',ns2,' x=',pxyd(1,ns2),' y=',pxyd(2,ns2)
c
c le sommet ns2 est il correct?
na = noarst( ns2 )
if( na .le. 0 ) then
write(imprim,*) 'tefoar: erreur sommet ',ns2,' sans arete'
ierr = 8
+ccc pause
return
endif
if( nosoar(4,na) .le. 0 ) then
write(imprim,*) 'tefoar: erreur sommet ',ns2,
% ' dans aucun triangle'
ierr = 8
+ccc pause
return
endif
c
-c recherche du triangle voisin dans le sens indirect de rotation
- nsens = -1
c le premier passage: recherche dans le sens ns1->ns2
ipas = 0
c
y2 = pxyd(2,ns2)
d12 = (x2-x1)**2 + (y2-y1)**2
c
+c recherche du triangle voisin dans le sens indirect de rotation
+ nsens = -1
+c
c recherche du no local du sommet ns1 dans l'un de ses triangles
- na01 = noarst( ns1 )
+ 10 na01 = noarst( ns1 )
if( na01 .le. 0 ) then
write(imprim,*) 'tefoar: sommet ',ns1,' sans arete'
ierr = 8
+ccc pause
return
endif
nt0 = nosoar(4,na01)
if( nt0 .le. 0 ) then
write(imprim,*) 'tefoar: sommet ',ns1,' dans aucun triangle'
ierr = 8
+ccc pause
return
endif
c
write(imprim,*)'tefoar:anomalie sommet ',ns1,
% 'non dans le triangle de sommets ',(nosotr(i),i=1,3)
ierr = 11
+ccc pause
return
endif
c
ns3 = nosotr( na0 )
ns4 = nosotr( na1 )
c
-cccc trace du triangle nt0 et de l'arete perdue
-ccc call mttrtr( pxyd, nt0, moartr, noartr, mosoar, nosoar,
-ccc % ncblan, ncjaun )
-ccc call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
-ccc call dvtrar( pxyd, ns3, ns4, ncbleu, nccyan )
-c
c point d'intersection du segment ns1-ns2 avec l'arete ns3-ns4
c ------------------------------------------------------------
call int1sd( ns1, ns2, ns3, ns4, pxyd, linter, x1, y1 )
c il faut tourner dans l'autre sens autour de ns1
if( nsens .lt. 0 ) then
nsens = 1
- nt0 = noarst( ns1 )
- goto 20
+ goto 10
endif
c
c dans les 2 sens, pas d'intersection => impossible
write(imprim,*) 'tefoar: arete ',ns1,' ',ns2,
% ' sans intersection avec les triangles actuels'
write(imprim,*) 'revoyez les lignes du contour'
- ierr = 11
+ ierr = 12
+ccc pause
return
endif
c
else
nt1 = nosoar(4,noar)
endif
-c
-cccc trace du triangle nt1 et de l'arete perdue
-ccc call mttrtr( pxyd, nt1, moartr, noartr, mosoar, nosoar,
-ccc % ncjaun, ncmage )
-ccc call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
+ if( nt1 .le. 0 ) then
+ write(imprim,*) 'erreur dans tefoar nt1=',nt1
+ read(lecteu,*) j
+ endif
c
c le numero des 3 sommets du triangle nt1 dans le sens direct
call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr )
if( abs( noartr(na1,nt1) ) .eq. noar ) goto 35
34 continue
c
-c trace du triangle nt1 et de l'arete perdue
- 35 continue
-ccc 35 call mttrtr( pxyd, nt1, moartr, noartr, mosoar, nosoar,
-ccc % ncjaun, ncmage )
-ccc call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
-c
c recherche de l'intersection de ns1-ns2 avec les 2 autres aretes de nt1
c ======================================================================
- na2 = na1
+ 35 na2 = na1
do 50 i1 = 1,2
c l'arete suivante
na2 = nosui3(na2)
noar = abs( noartr(na2,nt1) )
ns3 = nosoar( 1, noar )
ns4 = nosoar( 2, noar )
-ccc call dvtrar( pxyd, ns3, ns4, ncbleu, nccyan )
c
c point d'intersection du segment ns1-ns2 avec l'arete ns3-ns4
c ------------------------------------------------------------
c
c ici le sommet nsp est trop proche de l'arete perdue ns1-ns2
if( nsp .le. nbarpi ) then
-c point utilisateur ou frontalier non supprimable
- ierr = 11
- write(imprim,*) 'pause dans tefoar 1', d, d3, d4, d12
+c point utilisateur ou frontalier donc non supprimable
+ write(imprim,*) 'tefoar: sommet nsp=',nsp,
+ %' frontalier trop proche de l''arete perdue ns1=',ns1,'-ns2=',ns2
+ write(imprim,*)'s',nsp,': x=', pxyd(1,nsp),' y=', pxyd(2,nsp)
+ write(imprim,*)'s',ns1,': x=', pxyd(1,ns1),' y=', pxyd(2,ns1)
+ write(imprim,*)'s',ns2,': x=', pxyd(1,ns2),' y=', pxyd(2,ns2)
+ write(imprim,*)'arete s',ns1,'-s',ns2,
+ % ' coupe arete s',ns3,'-s',ns4,' en (x,y)'
+ write(imprim,*) 's',ns3,': x=', pxyd(1,ns3),' y=', pxyd(2,ns3)
+ write(imprim,*) 's',ns4,': x=', pxyd(1,ns4),' y=', pxyd(2,ns4)
+ write(imprim,*) 'intersection en: x=', x, ' y=', y
+ write(imprim,*) 'distance ns1-ns2=', sqrt(d12)
+ write(imprim,*) 'distance (x,y) au plus proche',ns3,ns4,'=',
+ % sqrt(d)
+ ierr = 13
+ccc pause
return
endif
c
c ------------------------------------------------------------------
ccc write(imprim,*) 'tefoar: le sommet ',nsp,' est supprime'
c construction de la liste des triangles de sommet nsp
- call trp1st( nsp, noarst, mosoar, nosoar, moartr, noartr,
+ call trp1st( nsp, noarst, mosoar, nosoar,
+ % moartr, mxartr, noartr,
% mxpitr, nbt, lapitr )
if( nbt .le. 0 ) then
c les triangles de sommet nsp ne forme pas une "boule"
c avec ce sommet nsp pour "centre"
write(imprim,*)
- % 'tefoar: pas d''etoile de triangles autour du sommet',nsp
-cccc trace des triangles de l'etoile du sommet nsp
-ccc tratri = .true.
-ccc call trpltr( nbt, lapitr, pxyd,
-ccc % moartr, noartr, mosoar, nosoar,
-ccc % ncroug, ncblan )
-ccc tratri = .false.
- ierr = 11
- write(imprim,*) 'pause dans tefoar 2'
- return
+ % 'tefoar: les triangles autour du sommet ',nsp,
+ % ' ne forme pas une etoile'
+ nbt = -nbt
endif
c
-c ajout des triangles de sommet ns1 a notrcf
+c ajout des triangles de sommet nsp a notrcf
nbtrc0 = nbtrcf
do 38 j=1,nbt
nt = lapitr(j)
c triangle ajoute
nbtrcf = nbtrcf + 1
notrcf( nbtrcf ) = nt
-ccc call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc % ncjaun, ncmage )
-ccc call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
38 continue
c
c ce sommet supprime n'appartient plus a aucun triangle
c ------------------------------------------------------------
call int1sd( ns1, ns2, ns3, ns4, pxyd,
% linter, x , y )
- if( linter .gt. 0 ) then
+ if( linter .gt. 0 ) then
c les 2 aretes s'intersectent en (x,y)
d = (x-x2)**2+(y-y2)**2
if( d .lt. dmin ) then
if( nt0 .gt. 0 ) goto 30
c
write(imprim,*) 'tefoar: algorithme defaillant'
- ierr = 11
+ ierr = 14
+ccc pause
return
endif
50 continue
c
c pas d'intersection differente de l'initiale => sommet sur ns1-ns2
-c rotation autour du sommet par l'arete suivant na1
+c tentative d'inversion des sommets de l'arete ns1-ns2
+ if( ipas .eq. 0 ) goto 25
write(imprim,*)
write(imprim,*) 'tefoar 50: revoyez vos donnees'
write(imprim,*) 'les lignes fermees doivent etre disjointes'
write(imprim,*) 'verifiez si elles ne se coupent pas'
- ierr = 13
+ ierr = 15
+ccc pause
return
c
c cas sans probleme : intersection differente de celle initiale
80 if( nbtrcf*3 .gt. mxarcf ) then
write(imprim,*) 'saturation du tableau noarcf'
ierr = 10
+ccc pause
return
endif
c
- call focftr( nbtrcf, notrcf, pxyd, noarst,
+ call focftr( nbtrcf, notrcf, nbarpi, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
- % nbarcf, n1arcf, noarcf,
+ % nbarcf, n1arcf, noarcf, nbstpe, nostpe,
% ierr )
if( ierr .ne. 0 ) return
c
noarcf( 2, na0 ) = n1
c
c depart avec 2 cf
- nbcf = 2
+ nbcf = 2
c
c triangulation directe des 2 contours fermes
c l'arete ns1-ns2 devient une arete de la triangulation des 2 cf
c ==============================================================
- call tridcf( nbcf, pxyd, noarst,
+ call tridcf( nbcf, nbstpe, nostpe, pxyd, noarst,
% mosoar, mxsoar, n1soar, nosoar,
% moartr, n1artr, noartr,
% mxarcf, n1arcf, noarcf, larmin,
% nbtrcf, notrcf, ierr )
+c
+ return
end
integer np(0:3),milieu(3)
c
c debut par l'arete 2 du triangle ntrp
+ ierr = 0
i1 = 2
i2 = 3
do 30 i=1,3
endif
110 continue
end
+
+
+ subroutine tesuqm( quamal, nbarpi, pxyd, noarst,
+ % mosoar, mxsoar, n1soar, nosoar,
+ % moartr, mxartr, n1artr, noartr,
+ % mxarcf, n1arcf, noarcf,
+ % larmin, notrcf, liarcf,
+ % quamin )
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but : supprimer de la triangulation les triangles de qualite
+c ----- inferieure a quamal
+c
+c entrees:
+c --------
+c quamal : qualite des triangles au dessous de laquelle supprimer des sommets
+c nbarpi : numero du dernier point interne impose par l'utilisateur
+c pxyd : tableau des coordonnees 2d des points
+c par point : x y distance_souhaitee
+c mosoar : nombre maximal d'entiers par arete et
+c indice dans nosoar de l'arete suivante dans le hachage
+c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
+c attention: mxsoar>3*mxsomm obligatoire!
+c moartr : nombre maximal d'entiers par arete du tableau noartr
+c
+c modifies:
+c ---------
+c noarst : noarst(i) numero d'une arete de sommet i
+c n1soar : no de l'eventuelle premiere arete libre dans le tableau nosoar
+c chainage des vides suivant en 3 et precedant en 2 de nosoar
+c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
+c chainage des aretes frontalieres, chainage du hachage des aretes
+c hachage des aretes = nosoar(1)+nosoar(2)*2
+c avec mxsoar>=3*mxsomm
+c une arete i de nosoar est vide <=> nosoar(1,i)=0 et
+c nosoar(2,arete vide)=l'arete vide qui precede
+c nosoar(3,arete vide)=l'arete vide qui suit
+c n1artr : numero du premier triangle vide dans le tableau noartr
+c le chainage des triangles vides se fait sur noartr(2,.)
+c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
+c arete1 = 0 si triangle vide => arete2 = triangle vide suivant
+c
+c auxiliaires :
+c -------------
+c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
+c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
+c larmin : tableau (mxarcf) auxiliaire d'entiers
+c notrcf : tableau (mxarcf) auxiliaire d'entiers
+c liarcf : tableau (mxarcf) auxiliaire d'entiers
+c
+c sortie :
+c --------
+c quamin : qualite minimale des triangles
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : alain perronnet Laboratoire JL Lions UPMC Paris Octobre 2006
+c....................................................................012
+ parameter ( lchain=6, mxtrqm=1024 )
+ common / unites / lecteu,imprim,intera,nunite(29)
+ double precision pxyd(3,*), quamal, qualit, quamin
+ integer nosoar(mosoar,mxsoar),
+ % noartr(moartr,mxartr),
+ % noarst(*)
+ integer nosotr(3), notraj(3)
+ double precision surtd2, s123, s142, s143, s234,
+ % s12, s34, a12
+ integer notrqm(mxtrqm)
+ double precision qutrqm(mxtrqm)
+ integer n1arcf(0:mxarcf),
+ % noarcf(3,mxarcf),
+ % larmin(mxarcf),
+ % notrcf(mxarcf),
+ % liarcf(mxarcf)
+c
+ ierr = 0
+c
+c initialisation du chainage des aretes des cf => 0 arete de cf
+ do 5 narete=1,mxsoar
+ nosoar( lchain, narete ) = -1
+ 5 continue
+c
+c recherche des triangles de plus basse qualite
+ quamin = 2.0
+ nbtrqm = 0
+ do 10 nt=1,mxartr
+ if( noartr(1,nt) .eq. 0 ) goto 10
+c le numero des 3 sommets du triangle nt
+ call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+c la qualite du triangle ns1 ns2 ns3
+ call qutr2d( pxyd(1,nosotr(1)), pxyd(1,nosotr(2)),
+ % pxyd(1,nosotr(3)), qualit )
+ if( qualit .lt. quamal ) then
+ if( nbtrqm .ge. mxtrqm ) goto 10
+ nbtrqm = nbtrqm + 1
+ notrqm(nbtrqm) = nt
+ qutrqm(nbtrqm) = qualit
+ endif
+ 10 continue
+c
+c tri croissant des qualites minimales des triangles
+ call tritas( nbtrqm, qutrqm, notrqm )
+c
+c le plus mauvais triangle
+ ntqmin = notrqm(1)
+ quamin = qutrqm(1)
+c
+ do 100 n=1,nbtrqm
+c
+c no du triangle de mauvaise qualite
+ ntqmin = notrqm( n )
+c
+c le triangle a t il ete traite?
+ if( noartr(1,ntqmin) .eq. 0 ) goto 100
+c
+ccc print *
+ccc print *,'tesuqm: triangle',ntqmin,' qualite=',qutrqm(n)
+ccc print *,'tesuqm: noartr(',ntqmin,')=',
+ccc % (noartr(j,ntqmin),j=1,moartr)
+cccc
+ccc do 12 j=1,3
+ccc noar = noartr(j,ntqmin)
+ccc print*,'arete',noar,' nosoar=',(nosoar(i,abs(noar)),i=1,mosoar)
+ccc 12 continue
+c
+c le numero des 3 sommets du triangle ntqmin
+ call nusotr( ntqmin, mosoar, nosoar, moartr, noartr, nosotr )
+c
+ccc do 15 j=1,3
+ccc nbt = nosotr(j)
+ccc print *,'sommet',nbt,': x=',pxyd(1,nbt),' y=',pxyd(2,nbt)
+ccc 15 continue
+c
+c recherche des triangles adjacents par les aretes de ntqmin
+ nbt = 0
+ do 20 j=1,3
+c le no de l'arete j dans nosoar
+ noar = abs( noartr(j,ntqmin) )
+c le triangle adjacent a l'arete j de ntqmin
+ if( nosoar(4,noar) .eq. ntqmin ) then
+ notraj(j) = nosoar(5,noar)
+ else
+ notraj(j) = nosoar(4,noar)
+ endif
+ if( notraj(j) .gt. 0 ) then
+c 1 triangle adjacent de plus
+ naop = j
+ nbt = nbt + 1
+ else
+c pas de triangle adjacent
+ notraj(j) = 0
+ endif
+ 20 continue
+c
+ if( nbt .eq. 1 ) then
+c
+c ntqmin a un seul triangle oppose par l'arete naop
+c le triangle a 2 aretes frontalieres est plat
+c l'arete commune aux 2 triangles est rendue Delaunay
+c ---------------------------------------------------
+ noar = abs( noartr(naop,ntqmin) )
+ if( nosoar(3,noar) .ne. 0 ) then
+c arete frontaliere
+ goto 100
+ endif
+c
+c l'arete appartient a deux triangles actifs
+c le numero des 4 sommets du quadrangle des 2 triangles
+ call mt4sqa( noar, moartr, noartr, mosoar, nosoar,
+ % ns1, ns2, ns3, ns4 )
+ if( ns4 .eq. 0 ) goto 100
+c
+c carre de la longueur de l'arete ns1 ns2
+ a12=(pxyd(1,ns2)-pxyd(1,ns1))**2+(pxyd(2,ns2)-pxyd(2,ns1))**2
+c
+c comparaison de la somme des aires des 2 triangles
+c -------------------------------------------------
+c calcul des surfaces des triangles 123 et 142 de cette arete
+ s123=surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+ s142=surtd2( pxyd(1,ns1), pxyd(1,ns4), pxyd(1,ns2) )
+ccc print *,'tesuqm: ns4=',ns4,' x=',pxyd(1,ns4),
+ccc % ' y=',pxyd(2,ns4)
+ccc print *,'tesuqm: s123=',s123,' s142=',s142
+ s12 = abs( s123 ) + abs( s142 )
+ if( s12 .le. 0.001*a12 ) goto 100
+c
+c calcul des surfaces des triangles 143 et 234 de cette arete
+ s143=surtd2( pxyd(1,ns1), pxyd(1,ns4), pxyd(1,ns3) )
+ s234=surtd2( pxyd(1,ns2), pxyd(1,ns3), pxyd(1,ns4) )
+ccc print *,'tesuqm: s143=',s143,' s234=',s234
+ s34 = abs( s234 ) + abs( s143 )
+ccc print *,'tesuqm: s12=',s12,' s34=',s34
+c
+ if( abs(s34-s12) .gt. 1d-14*s34 ) goto 100
+c
+c quadrangle convexe
+c echange de la diagonale 12 par 34 des 2 triangles
+c -------------------------------------------------
+ call te2t2t( noar, mosoar, n1soar, nosoar, noarst,
+ % moartr, noartr, noar34 )
+ccc print *,'tesuqm: sortie te2t2t avec noar34=',noar34
+c
+c
+ else if( nbt .eq. 2 ) then
+c
+c ntqmin a 2 triangles opposes par l'arete naop
+c essai de supprimer le sommet non frontalier
+c ---------------------------------------------
+ do 30 j=1,3
+ if( notraj(j) .eq. 0 ) goto 33
+ 30 continue
+c
+c arete sans triangle adjacent
+ 33 noar = abs( noartr(j,ntqmin) )
+ccc print *,'tesuqm: nosoar(',noar,')=',
+ccc % (nosoar(j,noar),j=1,mosoar)
+ if( noar .le. 0 ) goto 100
+c
+c ses 2 sommets
+ ns1 = nosoar(1,noar)
+ ns2 = nosoar(2,noar)
+c
+c ns3 l'autre sommet non frontalier
+ do 36 j=1,3
+ ns3 = nosotr(j)
+ if( ns3 .ne. ns1 .and. ns3 .ne. ns2 ) goto 40
+ 36 continue
+c
+ 40 if( ns3 .gt. nbarpi ) then
+c
+c le sommet ns3 non frontalier va etre supprime
+ccc print*,'tesuqm: ntqmin=',ntqmin,
+ccc % ' demande la suppression ns3=',ns3
+ call te1stm( ns3, nbarpi, pxyd, noarst,
+ % mosoar, mxsoar, n1soar, nosoar,
+ % moartr, mxartr, n1artr, noartr,
+ % mxarcf, n1arcf, noarcf,
+ % larmin, notrcf, liarcf, ierr )
+ccc if( ierr .eq. 0 ) then
+ccc print *,'tesuqm: st supprime ns3=',ns3
+ccc else
+ccc print *,'tesuqm: ST NON SUPPRIME ns3=',ns3,' ierr=',ierr
+ccc endif
+ endif
+c
+ endif
+c
+ 100 continue
+c
+ return
+ end
+
+
+ subroutine tritas( nb, a, noanc )
+c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but : tri croissant du tableau a de nb reels par la methode du tas
+c ----- methode due a williams et floyd o(n log n )
+c version avec un pointeur sur un tableau dont est extrait a
+c entrees:
+c --------
+c nb : nombre de termes du tableau a
+c a : les nb reels double precision a trier dans a
+c noanc : numero ancien position de l'information (souvent noanc(i)=i)
+c
+c sorties:
+c --------
+c a : les nb reels croissants dans a
+c noanc : numero ancien position de l'information
+c noanc(1)=no position pointeur sur a(1), ...
+c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : perronnet alain analyse numerique upmc paris fevrier 1991
+c ...................................................................012
+ integer noanc(1:nb)
+ integer pere,per,fil,fils1,fils2,fin
+ double precision a(1:nb),aux
+c
+c formation du tas sous forme d'un arbre binaire
+ fin = nb + 1
+c
+ do 20 pere = nb/2,1,-1
+c
+c descendre pere jusqu'a n dans a de facon a respecter
+c a(pere)>a(j) pour j fils ou petit fils de pere
+c c-a-d pour tout j tel que pere <= e(j/2)<j<nb+1
+c a(j/2) >= a(j)
+c >= a(j+1)
+c
+c protection du pere
+ per = pere
+c
+c le fils 1 du pere
+ 10 fils1 = 2 * per
+ if( fils1 .lt. fin ) then
+c il existe un fils1
+ fil = fils1
+ fils2 = fils1 + 1
+ if( fils2 .lt. fin ) then
+c il existe 2 fils . selection du plus grand
+ if( a(fils2) .gt. a(fils1) ) fil = fils2
+ endif
+c
+c ici fil est le plus grand des fils
+ if( a(per) .lt. a(fil) ) then
+c permutation de per et fil
+ aux = a(per)
+ a(per) = a(fil)
+ a(fil) = aux
+c le pointeur est aussi permute
+ naux = noanc(per)
+ noanc(per) = noanc(fil)
+ noanc(fil) = naux
+c le nouveau pere est le fils permute
+ per = fil
+ goto 10
+ endif
+ endif
+ 20 continue
+c
+c a chaque iteration la racine (plus grande valeur actuelle de a)
+c est mise a sa place (fin actuelle du tableau) et permutee avec
+c la valeur qui occupe cette place, puis descente de cette nouvelle
+c racine pour respecter le fait que tout pere est plus grand que tous
+c ses fils
+c c-a-d pour tout j tel que pere <= e(j/2)<j<nb+1
+c a(j/2) >= a(j)
+c >= a(j+1)
+ do 50 fin=nb,2,-1
+c la permutation premier dernier
+ aux = a(fin)
+ a(fin) = a(1)
+ a(1) = aux
+c le pointeur est aussi permute
+ naux = noanc(fin)
+ noanc(fin) = noanc(1)
+ noanc(1) = naux
+c
+c descendre a(1) entre 1 et fin
+ per = 1
+c
+c le fils 1 du pere
+ 30 fils1 = 2 * per
+ if( fils1 .lt. fin ) then
+c il existe un fils1
+ fil = fils1
+ fils2 = fils1 + 1
+ if( fils2 .lt. fin ) then
+c il existe 2 fils . selection du plus grand
+ if( a(fils2) .gt. a(fils1) ) fil = fils2
+ endif
+c
+c ici fil est le plus grand des fils
+ if( a(per) .lt. a(fil) ) then
+c permutation de per et fil
+ aux = a(per)
+ a(per) = a(fil)
+ a(fil) = aux
+c le pointeur est aussi permute
+ naux = noanc(per)
+ noanc(per) = noanc(fil)
+ noanc(fil) = naux
+c le nouveau pere est le fils permute
+ per = fil
+ goto 30
+ endif
+ endif
+ 50 continue
+ end
#include "SMESH_ActorUtils.h"
#include "SMDS_Mesh.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMESH_Actor.h"
#include "SMESH_ControlsDef.hxx"
#include "SalomeApp_Application.h"
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
switch(aType){
case SMDSAbs_Volume:{
+ aConnect.clear();
std::vector<int> aConnectivities;
- GetConnect(aNodesIter,aConnect);
// Convertions connectivities from SMDS to VTK
if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
- for (int k = 0; k < aNbNodes; k++) {
+
+ if ( const SMDS_PolyhedralVolumeOfNodes* ph =
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+ {
+ aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
+ anIdList->SetNumberOfIds( aNbNodes );
+ }
+ for (int k = 0; k < aNbNodes; k++)
aConnectivities.push_back(k);
- }
- } else if (aNbNodes == 4) {
+ } else if (aNbNodes == 4) {
static int anIds[] = {0,2,1,3};
for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
else {
}
+ if ( aConnect.empty() )
+ GetConnect(aNodesIter,aConnect);
+
if (aConnectivities.size() > 0) {
for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+
#include "utilities.h"
using namespace std;
SMDS_NodeArrayElemIterator( s, & s[ l ] ) {}
};
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MyEdgeIterator(const SMDS_FaceOfNodes* face):myIndex(0) {
+ myElems.reserve( face->NbNodes() );
+ for ( int i = 0; i < face->NbNodes(); ++i ) {
+ const SMDS_MeshElement* edge =
+ SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+ if ( edge )
+ myElems.push_back( edge );
+ }
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator
(SMDSAbs_ElementType type) const
{
case SMDSAbs_Node:
return SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes));
case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
+ return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
break;
default:
return SMDS_ElemIteratorPtr
const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2)
{
+ if ( !node1 ) return 0;
const SMDS_MeshEdge * toReturn=NULL;
//PROFILER_Init();
//PROFILER_Set();
- SMDS_ElemIteratorPtr it1=node1->edgesIterator();
+ SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
//PROFILER_Get(0);
//PROFILER_Set();
while(it1->more()) {
- const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *> (it1->next());
- SMDS_ElemIteratorPtr it2=e->nodesIterator();
- while(it2->more()) {
- if(it2->next()->GetID()==node2->GetID()) {
- toReturn = e;
- break;
- }
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
+ toReturn = static_cast<const SMDS_MeshEdge*>( e );
+ break;
}
}
//PROFILER_Get(1);
const SMDS_MeshNode * node2,
const SMDS_MeshNode * node3)
{
- if ( !node1 || !node2 || !node3 ) return 0;
- const SMDS_MeshEdge * toReturn = NULL;
- SMDS_ElemIteratorPtr it1 = node1->edgesIterator();
+ if ( !node1 ) return 0;
+ SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
while(it1->more()) {
- const SMDS_MeshEdge * e = static_cast<const SMDS_MeshEdge *> (it1->next());
- SMDS_ElemIteratorPtr it2 = e->nodesIterator();
- int tmp = 0;
- while(it2->more()) {
- int nID = it2->next()->GetID();
- if( nID==node2->GetID() || nID==node3->GetID() ) {
- tmp++;
- if(tmp==2) {
- toReturn = e;
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 3 ) {
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ while(it2->more()) {
+ const SMDS_MeshElement* n = it2->next();
+ if( n!=node1 &&
+ n!=node2 &&
+ n!=node3 )
+ {
+ e = 0;
break;
}
}
+ if ( e )
+ return static_cast<const SMDS_MeshEdge *> (e);
}
}
- return toReturn;
+ return 0;
}
const SMDS_MeshNode *node2,
const SMDS_MeshNode *node3)
{
- if ( !node1 || !node2 || !node3 ) return 0;
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- bool node2found, node3found;
-
- SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ if ( !node1 ) return 0;
+ SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
while(it1->more()) {
- face = static_cast<const SMDS_MeshFace*>(it1->next());
- if(face->NbNodes()!=3) continue;
- SMDS_ElemIteratorPtr it2 = face->nodesIterator();
- node2found = false;
- node3found = false;
- while(it2->more()) {
- node = it2->next();
- if(node->GetID()==node2->GetID()) node2found = true;
- if(node->GetID()==node3->GetID()) node3found = true;
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 3 ) {
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ while(it2->more()) {
+ const SMDS_MeshElement* n = it2->next();
+ if( n!=node1 &&
+ n!=node2 &&
+ n!=node3 )
+ {
+ e = 0;
+ break;
+ }
+ }
+ if ( e )
+ return static_cast<const SMDS_MeshFace *> (e);
}
- if( node2found && node3found )
- return face;
}
- return NULL;
+ return 0;
}
SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
const SMDS_MeshNode *node3,
const SMDS_MeshNode *node4)
{
- if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) )
- return NULL;
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- bool node2found, node3found, node4found;
- SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ if ( !node1 ) return 0;
+ SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
while(it1->more()) {
- face = static_cast<const SMDS_MeshFace *>(it1->next());
- if(face->NbNodes()!=4) continue;
- SMDS_ElemIteratorPtr it2 = face->nodesIterator();
- node2found = false;
- node3found = false;
- node4found = false;
- while(it2->more()) {
- node=it2->next();
- if(node->GetID()==node2->GetID()) node2found = true;
- if(node->GetID()==node3->GetID()) node3found = true;
- if(node->GetID()==node4->GetID()) node4found = true;
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 4 ) {
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ while(it2->more()) {
+ const SMDS_MeshElement* n = it2->next();
+ if( n!=node1 &&
+ n!=node2 &&
+ n!=node3 &&
+ n!=node4 )
+ {
+ e = 0;
+ break;
+ }
+ }
+ if ( e )
+ return static_cast<const SMDS_MeshFace *> (e);
}
- if( node2found && node3found && node4found )
- return face;
}
- return NULL;
+ return 0;
}
SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
const SMDS_MeshNode *node5,
const SMDS_MeshNode *node6)
{
- if( (node1==NULL) || (node2==NULL) || (node3==NULL) ||
- (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL;
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ if ( !node1 ) return 0;
+ SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
while(it1->more()) {
- face = static_cast<const SMDS_MeshFace*>(it1->next());
- if(face->NbNodes()!=6) continue;
- SMDS_ElemIteratorPtr it2 = face->nodesIterator();
- int tmp = 0;
- while(it2->more()) {
- node = it2->next();
- if(node->GetID()==node2->GetID()) tmp++;
- if(node->GetID()==node3->GetID()) tmp++;
- if(node->GetID()==node4->GetID()) tmp++;
- if(node->GetID()==node5->GetID()) tmp++;
- if(node->GetID()==node6->GetID()) tmp++;
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 6 ) {
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ while(it2->more()) {
+ const SMDS_MeshElement* n = it2->next();
+ if( n!=node1 &&
+ n!=node2 &&
+ n!=node3 &&
+ n!=node4 &&
+ n!=node5 &&
+ n!=node6 )
+ {
+ e = 0;
+ break;
+ }
+ }
+ if ( e )
+ return static_cast<const SMDS_MeshFace *> (e);
}
- if( tmp==5 )
- return static_cast<const SMDS_MeshFace*>(face);
}
- return NULL;
+ return 0;
}
const SMDS_MeshNode *node7,
const SMDS_MeshNode *node8)
{
- if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ||
- (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) )
- return NULL;
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ if ( !node1 ) return 0;
+ SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
while(it1->more()) {
- face = static_cast<const SMDS_MeshFace *>(it1->next());
- if(face->NbNodes()!=8) continue;
- SMDS_ElemIteratorPtr it2 = face->nodesIterator();
- int tmp = 0;
- while(it2->more()) {
- node = it2->next();
- if(node->GetID()==node2->GetID()) tmp++;
- if(node->GetID()==node3->GetID()) tmp++;
- if(node->GetID()==node4->GetID()) tmp++;
- if(node->GetID()==node5->GetID()) tmp++;
- if(node->GetID()==node6->GetID()) tmp++;
- if(node->GetID()==node7->GetID()) tmp++;
- if(node->GetID()==node8->GetID()) tmp++;
+ const SMDS_MeshElement * e = it1->next();
+ if ( e->NbNodes() == 8 ) {
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ while(it2->more()) {
+ const SMDS_MeshElement* n = it2->next();
+ if( n!=node1 &&
+ n!=node2 &&
+ n!=node3 &&
+ n!=node4 &&
+ n!=node5 &&
+ n!=node6 &&
+ n!=node7 &&
+ n!=node8 )
+ {
+ e = 0;
+ break;
+ }
+ }
+ if ( e )
+ return static_cast<const SMDS_MeshFace *> (e);
}
- if( tmp==7 )
- return face;
}
- return NULL;
+ return 0;
}
const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
{
- int nbNodes = nodes.size();
- if (nbNodes < 1) return NULL;
-
- bool isFound = true;
- const SMDS_MeshFace * face;
- set<const SMDS_MeshFace *> faces;
-
- for (int inode = 0; inode < nbNodes && isFound; inode++) {
- if ( !nodes[ inode ]) return 0;
-
- set<const SMDS_MeshFace *> new_faces;
-
- SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator();
+ if ( nodes.size() > 2 && nodes[0] ) {
+ SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
while (itF->more()) {
- face = static_cast<const SMDS_MeshFace *>(itF->next());
- if (face->NbNodes() == nbNodes) {
- if (inode == 0 || faces.find(face) != faces.end()) {
- new_faces.insert(face);
+ const SMDS_MeshElement* f = itF->next();
+ if ( f->NbNodes() == nodes.size() ) {
+ SMDS_ElemIteratorPtr it2 = f->nodesIterator();
+ while(it2->more()) {
+ if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
+ f = 0;
+ break;
+ }
}
+ if ( f )
+ return static_cast<const SMDS_MeshFace *> (f);
}
}
- faces = new_faces;
- if (new_faces.size() == 0) {
- isFound = false;
- }
}
-
- if (isFound)
- return face;
-
return NULL;
}
return myPosition;
}
+//=======================================================================
+/*!
+ * \brief Iterator on list of elements
+ */
+//=======================================================================
+
class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
{
NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
+ SMDSAbs_ElementType myType;
public:
- SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s):
- myIterator(s)
+ SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s,
+ SMDSAbs_ElementType type):
+ myIterator(s), myType(type)
{}
bool more()
{
+ if ( myType != SMDSAbs_All ) {
+ while ( myIterator.More() && myIterator.Value()->GetType() != myType)
+ myIterator.Next();
+ }
return myIterator.More() != Standard_False;
}
};
SMDS_ElemIteratorPtr SMDS_MeshNode::
- GetInverseElementIterator() const
+ GetInverseElementIterator(SMDSAbs_ElementType type) const
{
- return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements));
+ return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type));
}
// Same as GetInverseElementIterator but the create iterator only return
return myInverseElements.IsEmpty() != Standard_False;
}
+//================================================================================
+/*!
+ * \brief Count inverse elements of given type
+ */
+//================================================================================
+
+int SMDS_MeshNode::NbInverseNodes(SMDSAbs_ElementType type) const
+{
+ if ( type == SMDSAbs_All )
+ return myInverseElements.Extent();
+ int nb = 0;
+ NCollection_List<const SMDS_MeshElement*>::Iterator it( myInverseElements );
+ for ( ; it.More(); it.Next() )
+ if ( it.Value()->GetType() == type )
+ nb++;
+ return nb;
+}
+
///////////////////////////////////////////////////////////////////////////////
/// To be used with STL set
///////////////////////////////////////////////////////////////////////////////
void RemoveInverseElement(const SMDS_MeshElement * parent);
void ClearInverseElements();
bool emptyInverseElements();
- SMDS_ElemIteratorPtr GetInverseElementIterator() const;
+ SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
+ int NbInverseNodes(SMDSAbs_ElementType type=SMDSAbs_All) const;
void SetPosition(const SMDS_PositionPtr& aPos);
const SMDS_PositionPtr& GetPosition() const;
SMDSAbs_ElementType GetType() const;
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_SetIterator.hxx"
+#include "SMDS_Mesh.hxx"
+
#include "utilities.h"
using namespace std;
SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
};
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MyEdgeIterator(const SMDS_MeshFace* face):myIndex(0) {
+ myElems.reserve( face->NbNodes() );
+ for ( int i = 0; i < face->NbNodes(); ++i ) {
+ const SMDS_MeshElement* edge =
+ SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+ if ( edge )
+ myElems.push_back( edge );
+ }
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
(SMDSAbs_ElementType type) const
{
case SMDSAbs_Node:
return SMDS_ElemIteratorPtr(new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes));
case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_PolygonalFaceOfNodes not implemented");
+ return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
break;
default:
return SMDS_ElemIteratorPtr
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
#include "utilities.h"
#include <set>
//purpose : Create a volume of many faces
//=======================================================================
SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
- (std::vector<const SMDS_MeshNode *> nodes,
- std::vector<int> quantities)
+ (vector<const SMDS_MeshNode *> nodes,
+ vector<int> quantities)
: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
{
ChangeNodes(nodes, quantities);
//function : ChangeNodes
//purpose :
//=======================================================================
-bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
- std::vector<int> quantities)
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const vector<const SMDS_MeshNode *>& nodes,
+ const vector<int>& quantities)
{
myNodesByFaces = nodes;
myQuantities = quantities;
- // Init fields of parent class
- int aNbNodes = 0;
- std::set<const SMDS_MeshNode *> aSet;
- int nodes_len = nodes.size();
- for (int j = 0; j < nodes_len; j++) {
- if (aSet.find(nodes[j]) == aSet.end()) {
- aSet.insert(nodes[j]);
- aNbNodes++;
- }
- }
-
- int k = 0;
-#ifndef WNT
- const SMDS_MeshNode* aNodes [aNbNodes];
-#else
- const SMDS_MeshNode** aNodes = (const SMDS_MeshNode **)new SMDS_MeshNode*[aNbNodes];
-#endif
- std::set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
- for (; anIter != aSet.end(); anIter++, k++) {
- aNodes[k] = *anIter;
- }
+ // Init fields of parent class, it allows to get only unique nodes(?)
+ set<const SMDS_MeshNode *> aSet;
+ aSet.insert( nodes.begin(), nodes.end());
//SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes);
delete [] myNodes;
- //myNbNodes = nodes.size();
- myNbNodes = aNbNodes;
+ myNbNodes = aSet.size();
myNodes = new const SMDS_MeshNode* [myNbNodes];
- for (int i = 0; i < myNbNodes; i++) {
- //myNodes[i] = nodes[i];
- myNodes[i] = aNodes[i];
- }
-
-#ifdef WNT
- delete [] aNodes;
-#endif
+ set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
+ for (int k=0; anIter != aSet.end(); anIter++, k++)
+ myNodes[k] = *anIter;
return true;
}
+//=======================================================================
+//function : NbEdges
+//purpose :
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbNodes() const
+{
+ return myNodesByFaces.size();
+}
+
//=======================================================================
//function : NbEdges
//purpose :
{
return false;
}
+
+/// ===================================================================
+/*!
+ * \brief Iterator on node of volume
+ */
+/// ===================================================================
+
+struct _MyIterator:public SMDS_NodeVectorElemIterator
+{
+ _MyIterator(const vector<const SMDS_MeshNode *>& nodes):
+ SMDS_NodeVectorElemIterator( nodes.begin(), nodes.end()) {}
+};
+
+/// ===================================================================
+/*!
+ * \brief Iterator on faces or edges of volume
+ */
+/// ===================================================================
+
+class _MySubIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) {
+ SMDS_VolumeTool vTool(vol);
+ if (type == SMDSAbs_Face)
+ vTool.GetAllExistingFaces( myElems );
+ else
+ vTool.GetAllExistingFaces( myElems );
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
+//================================================================================
+/*!
+ * \brief Return Iterator of sub elements
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
+{
+ switch(type)
+ {
+ case SMDSAbs_Volume:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new _MyIterator(myNodesByFaces));
+ case SMDSAbs_Face:
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
+ case SMDSAbs_Edge:
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
+ default:
+ MESSAGE("ERROR : Iterator not implemented");
+ return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator on unique nodes
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const
+{
+ return SMDS_ElemIteratorPtr
+ (new SMDS_NodeArrayElemIterator( myNodes, & myNodes[ myNbNodes ]));
+}
+
+//================================================================================
+/*!
+ * \brief Return node by its index
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const
+{
+ return myNodesByFaces[ WrappedIndex( ind )];
+}
virtual SMDSAbs_ElementType GetType() const;
virtual bool IsPoly() const { return true; };
- bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
- std::vector<int> quantities);
+ bool ChangeNodes (const std::vector<const SMDS_MeshNode *> & nodes,
+ const std::vector<int> & quantities);
- //virtual int NbNodes() const;
+ virtual int NbNodes() const;
virtual int NbEdges() const;
virtual int NbFaces() const;
// 1 <= face_ind <= NbFaces()
// 1 <= node_ind <= NbFaceNodes()
+ const std::vector<int> & GetQuanities() const { return myQuantities; }
+
virtual void Print (std::ostream & OS) const;
- protected:
- //virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+ /*!
+ * \brief Return node by its index
+ */
+ virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+ /*!
+ * \brief Return iterator on unique nodes
+ */
+ SMDS_ElemIteratorPtr uniqueNodesIterator() const;
+ /*!
+ * \brief Return nb of unique nodes
+ */
+ int NbUniqueNodes() const { return myNbNodes; }
+
+protected:
+ SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
private:
// usage disabled
#include "SMDS_SetIterator.hxx"
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
#include "utilities.h"
return SMDS_ElemIteratorPtr
(new _MyInterlacedNodeElemIterator ( interlacedNodesIterator() ));
}
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) {
+ myElems.reserve( face->NbNodes() );
+ SMDS_ElemIteratorPtr nIt = face->interlacedNodesElemIterator();
+ const SMDS_MeshNode* n0 = face->GetNode( -1 );
+ while ( nIt->more() ) {
+ const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 );
+ if ( edge )
+ myElems.push_back( edge );
+ n0 = n1;
+ }
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
//=======================================================================
//function : elementsIterator
case SMDSAbs_Node:
return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes));
case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_QuadraticFaceOfNodes not implemented");
+ return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
break;
default:
return SMDS_ElemIteratorPtr
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
#include "utilities.h"
SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
};
+/// ===================================================================
+/*!
+ * \brief Iterator on faces or edges of volume
+ */
+/// ===================================================================
+
+class _MySubIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) {
+ SMDS_VolumeTool vTool(vol);
+ if (type == SMDSAbs_Face)
+ vTool.GetAllExistingFaces( myElems );
+ else
+ vTool.GetAllExistingFaces( myElems );
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
//=======================================================================
//function : elementsIterator
//purpose :
case SMDSAbs_Node:
return SMDS_ElemIteratorPtr(new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes));
case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_QuadraticVolumeOfNodes not implemented");
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
break;
case SMDSAbs_Face:
- MESSAGE("Error : face iterator for SMDS_QuadraticVolumeOfNodes not implemented");
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
break;
default:
return SMDS_ElemIteratorPtr
#include "SMDS_Iterator.hxx"
///////////////////////////////////////////////////////////////////////////////
-/// specific SMDS_Iterator iterating over abstract set of values like STL containers
+/// Accessors to value pointed by iterator
+///////////////////////////////////////////////////////////////////////////////
+
+namespace SMDS {
+
+ template<typename VALUE,typename VALUE_SET_ITERATOR>
+ struct SimpleAccessor {
+ static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) *it; }
+ };
+
+ template<typename VALUE,typename VALUE_SET_ITERATOR>
+ struct KeyAccessor {
+ static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->first; }
+ };
+
+ template<typename VALUE,typename VALUE_SET_ITERATOR>
+ struct ValueAccessor {
+ static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->second; }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// SMDS_Iterator iterating over abstract set of values like STL containers
///
/// BE CAREFUL: iterator pointed value is static_cast'ed to VALUE
///
///////////////////////////////////////////////////////////////////////////////
-template<typename VALUE, typename VALUE_SET_ITERATOR>
+template<typename VALUE,
+ typename VALUE_SET_ITERATOR,
+ typename ACCESOR=SMDS::SimpleAccessor<VALUE,VALUE_SET_ITERATOR> >
class SMDS_SetIterator : public SMDS_Iterator<VALUE>
{
protected:
virtual bool more() { return _beg != _end; }
/// Return the current object and step to the next one
- virtual VALUE next() { return static_cast<VALUE>( *_beg++ ); }
+ virtual VALUE next() { return ACCESOR::value( _beg++ ); }
+};
+///////////////////////////////////////////////////////////////////////////////
+/// map iterators
+///////////////////////////////////////////////////////////////////////////////
+
+#include <map>
+/*!
+ * \brief iterator on values of a map
+ */
+template<typename M>
+struct SMDS_mapIterator : public SMDS_SetIterator< typename M::mapped_type, typename M::const_iterator,
+ SMDS::ValueAccessor<typename M::mapped_type,
+ typename M::const_iterator> > {
+ typedef SMDS_SetIterator< typename M::mapped_type, typename M::const_iterator,
+ SMDS::ValueAccessor<typename M::mapped_type,
+ typename M::const_iterator> > parent_type;
+ SMDS_mapIterator(const M& m):parent_type(m.begin(),m.end()) {}
+};
+/*!
+ * \brief reverse iterator on values of a map
+ */
+template<typename M>
+struct SMDS_mapReverseIterator : public SMDS_SetIterator< typename M::mapped_type,
+ typename M::const_reverse_iterator,
+ SMDS::ValueAccessor<typename M::mapped_type,
+ typename M::const_reverse_iterator> > {
+ typedef SMDS_SetIterator< typename M::mapped_type, typename M::const_reverse_iterator,
+ SMDS::ValueAccessor<typename M::mapped_type,
+ typename M::const_reverse_iterator> > parent_type;
+ SMDS_mapReverseIterator(const M& m):parent_type(m.rbegin(),m.rend()) {}
+};
+/*!
+ * \brief iterator on keys of a map
+ */
+template<typename M>
+struct SMDS_mapKeyIterator : public SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+ SMDS::KeyAccessor<typename M::key_type,
+ typename M::const_iterator> > {
+ typedef SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+ SMDS::KeyAccessor<typename M::key_type,
+ typename M::const_iterator> > parent_type;
+ SMDS_mapKeyIterator(const M& m):parent_type(m.begin(),m.end()) {}
+};
+/*!
+ * \brief reverse iterator on keys of a map
+ */
+template<typename M>
+struct SMDS_mapKeyReverseIterator : public SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+ SMDS::KeyAccessor<typename M::key_type,
+ typename M::const_iterator> > {
+ typedef SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+ SMDS::KeyAccessor<typename M::key_type,
+ typename M::const_iterator> > parent_type;
+ SMDS_mapKeyReverseIterator(const M& m):parent_type(m.rbegin(),m.rend()) {}
};
+///////////////////////////////////////////////////////////////////////////////
// useful specifications
+///////////////////////////////////////////////////////////////////////////////
#include <vector>
#include "SMDS_VolumeOfNodes.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
#include "utilities.h"
+#include <vector>
+
using namespace std;
///////////////////////////////////////////////////////////////////////////////
return 0;
}
+/// ===================================================================
+/*!
+ * \brief Iterator on node of volume
+ */
+/// ===================================================================
+
class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
{
public:
SMDS_NodeArrayElemIterator( s, & s[ l ]) {}
};
+/// ===================================================================
+/*!
+ * \brief Iterator on faces or edges of volume
+ */
+/// ===================================================================
+
+class _MySubIterator : public SMDS_ElemIterator
+{
+ vector< const SMDS_MeshElement* > myElems;
+ int myIndex;
+public:
+ _MySubIterator(const SMDS_VolumeOfNodes* vol, SMDSAbs_ElementType type):myIndex(0) {
+ SMDS_VolumeTool vTool(vol);
+ if (type == SMDSAbs_Face)
+ vTool.GetAllExistingFaces( myElems );
+ else
+ vTool.GetAllExistingFaces( myElems );
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more() { return myIndex < myElems.size(); }
+
+ /// Return the current object and step to the next one
+ virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
{
switch(type)
return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
case SMDSAbs_Node:
return SMDS_ElemIteratorPtr(new SMDS_VolumeOfNodes_MyIterator(myNodes,myNbNodes));
+ case SMDSAbs_Face:
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
+ case SMDSAbs_Edge:
+ return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
default:
MESSAGE("ERROR : Iterator not implemented");
return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_Mesh.hxx"
#include "utilities.h"
return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
}
- int minInd = theNode1Index < theNode2Index ? theNode1Index : theNode2Index;
- int maxInd = theNode1Index < theNode2Index ? theNode2Index : theNode1Index;
+ int minInd = min( theNode1Index, theNode2Index );
+ int maxInd = max( theNode1Index, theNode2Index );
if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd )
return false;
return -1;
}
+//================================================================================
+/*!
+ * \brief Fill vector with boundary faces existing in the mesh
+ * \param faces - vector of found nodes
+ * \retval int - nb of found faces
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces)
+{
+ faces.clear();
+ faces.reserve( NbFaces() );
+ for ( int iF = 0; iF < NbFaces(); ++iF ) {
+ const SMDS_MeshFace* face = 0;
+ const SMDS_MeshNode** nodes = GetFaceNodes( iF );
+ switch ( NbFaceNodes( iF )) {
+ case 3:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
+ case 4:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
+ case 6:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
+ nodes[3], nodes[4], nodes[5]); break;
+ case 8:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7]); break;
+ }
+ if ( face )
+ faces.push_back( face );
+ }
+ return faces.size();
+}
+
+
+//================================================================================
+/*!
+ * \brief Fill vector with boundary edges existing in the mesh
+ * \param edges - vector of found edges
+ * \retval int - nb of found faces
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+{
+ edges.clear();
+ edges.reserve( myVolumeNbNodes * 2 );
+ for ( int i = 0; i < myVolumeNbNodes; ++i ) {
+ for ( int j = i + 1; j < myVolumeNbNodes; ++j ) {
+ if ( IsLinked( i, j )) {
+ const SMDS_MeshElement* edge =
+ SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] );
+ if ( edge )
+ edges.push_back( edge );
+ }
+ }
+ }
+ return edges.size();
+}
+
//=======================================================================
//function : IsFreeFace
//purpose : check that only one volume is build on the face nodes
continue; // opposite side
}
// remove a volume from volNbShared map
- volNbShared.erase( vNbIt );
+ volNbShared.erase( vNbIt-- );
}
// here volNbShared contains only volumes laying on the
int GetNodeIndex(const SMDS_MeshNode* theNode) const;
// Return an index of theNode
+ int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const;
+ // Fill vector with boundary edges existing in the mesh
+
// -------------
// info on faces
// -------------
// Return index of a face formed by theFaceNodesIndices
// Return -1 if a face not found
+ int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces);
+ // Fill vector with boundary faces existing in the mesh
+
// ------------------------
// static methods for faces
// ------------------------
SMESH_Hypothesis.hxx \
SMESH_HypoFilter.hxx \
SMESH_Algo.hxx \
+ SMESH_0D_Algo.hxx \
SMESH_1D_Algo.hxx \
SMESH_2D_Algo.hxx \
SMESH_3D_Algo.hxx \
SMESH_SequenceOfElemPtr.hxx \
SMESH_SequenceOfNode.hxx \
SMESH_MesherHelper.hxx \
+ SMESH_Octree.hxx \
+ SMESH_OctreeNode.hxx \
+ SMESH_Comment.hxx \
+ SMESH_ComputeError.hxx \
SMESH_SMESH.hxx
# Libraries targets
SMESH_subMesh.cxx \
SMESH_Hypothesis.cxx \
SMESH_Algo.cxx \
+ SMESH_0D_Algo.cxx \
SMESH_1D_Algo.cxx \
SMESH_2D_Algo.cxx \
SMESH_3D_Algo.cxx \
SMESH_Block.cxx \
SMESH_Pattern.cxx \
SMESH_HypoFilter.cxx \
- SMESH_MesherHelper.cxx
+ SMESH_MesherHelper.cxx \
+ SMESH_Octree.cxx \
+ SMESH_OctreeNode.cxx
# additionnal information to compile and link file
libSMESHimpl_la_CPPFLAGS = \
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_0D_Algo.cxx
+// Module : SMESH
+// $Header$
+
+#include "SMESH_0D_Algo.hxx"
+#include "SMESH_Gen.hxx"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH_0D_Algo::SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen)
+ : SMESH_Algo(hypId, studyId, gen)
+{
+ _type = ALGO_0D;
+ gen->_map0D_Algo[hypId] = this;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH_0D_Algo::~SMESH_0D_Algo()
+{
+}
+
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_0D_Algo.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_0D_ALGO_HXX_
+#define _SMESH_0D_ALGO_HXX_
+
+#include "SMESH_Algo.hxx"
+
+class SMESH_0D_Algo: public SMESH_Algo
+{
+public:
+ SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~SMESH_0D_Algo();
+};
+
+#endif
// $Header$
#include "SMESH_Algo.hxx"
+#include "SMESH_Comment.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_HypoFilter.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESHDS_SubMesh.hxx"
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepLProp.hxx>
#include <BRep_Tool.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Surface.hxx>
+#include <TopExp.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+
#include "utilities.h"
#include <algorithm>
SMESH_Algo::SMESH_Algo(int hypId, int studyId,
SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen)
{
-// _compatibleHypothesis.push_back("hypothese_bidon");
- _type = ALGO;
- gen->_mapAlgo[hypId] = this;
+ gen->_mapAlgo[hypId] = this;
- _onlyUnaryInput = _requireDescretBoundary = true;
- _quadraticMesh = false;
+ _onlyUnaryInput = _requireDescretBoundary = _requireShape = true;
+ _quadraticMesh = false;
+ _error = COMPERR_OK;
}
//=============================================================================
TopLoc_Location L;
Handle(Geom_Curve) C = BRep_Tool::Curve(E, L, UMin, UMax);
GeomAdaptor_Curve AdaptCurve(C);
- GCPnts_AbscissaPoint gabs;
- double length = gabs.Length(AdaptCurve, UMin, UMax);
+ double length = GCPnts_AbscissaPoint::Length(AdaptCurve, UMin, UMax);
return length;
}
return false;
}
+//================================================================================
+/*!
+ * \brief Return continuity of two edges
+ * \param E1 - the 1st edge
+ * \param E2 - the 2nd edge
+ * \retval GeomAbs_Shape - regularity at the junction between E1 and E2
+ */
+//================================================================================
+
+GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1,
+ const TopoDS_Edge & E2)
+{
+ TopoDS_Vertex V = TopExp::LastVertex (E1, true);
+ if ( !V.IsSame( TopExp::FirstVertex(E2, true )))
+ if ( !TopExp::CommonVertex( E1, E2, V ))
+ return GeomAbs_C0;
+ Standard_Real u1 = BRep_Tool::Parameter( V, E1 );
+ Standard_Real u2 = BRep_Tool::Parameter( V, E2 );
+ BRepAdaptor_Curve C1( E1 ), C2( E2 );
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ return BRepLProp::Continuity(C1, C2, u1, u2);
+ }
+ catch (Standard_Failure) {
+ }
+ return GeomAbs_C0;
+}
+
+//================================================================================
+/*!
+ * \brief Return the node built on a vertex
+ * \param V - the vertex
+ * \param meshDS - mesh
+ * \retval const SMDS_MeshNode* - found node or NULL
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
+ SMESHDS_Mesh* meshDS)
+{
+ if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(V) ) {
+ SMDS_NodeIteratorPtr nIt= sm->GetNodes();
+ if (nIt->more())
+ return nIt->next();
+ }
+ return 0;
+}
+
//================================================================================
/*!
* \brief Sets event listener to submeshes if necessary
- * \param subMesh - submesh where algo is set
+ * \param subMesh - submesh where algo is set
*
* After being set, event listener is notified on each event of a submesh.
* By default non listener is set
void SMESH_Algo::SetEventListener(SMESH_subMesh* /*subMesh*/)
{
}
+
+//================================================================================
+/*!
+ * \brief Allow algo to do something after persistent restoration
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//================================================================================
+
+void SMESH_Algo::SubmeshRestored(SMESH_subMesh* /*subMesh*/)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Computes mesh without geometry
+ * \param aMesh - the mesh
+ * \param aHelper - helper that must be used for adding elements to \aaMesh
+ * \retval bool - is a success
+ */
+//================================================================================
+
+bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/)
+{
+ return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
+}
+
+//================================================================================
+/*!
+ * \brief store error and comment and then return ( error == COMPERR_OK )
+ */
+//================================================================================
+
+bool SMESH_Algo::error(int error, const SMESH_Comment& comment)
+{
+ _error = error;
+ _comment = comment;
+ return ( error == COMPERR_OK );
+}
+
+//================================================================================
+/*!
+ * \brief store error and return ( error == COMPERR_OK )
+ */
+//================================================================================
+
+bool SMESH_Algo::error(SMESH_ComputeErrorPtr error)
+{
+ if ( error ) {
+ _error = error->myName;
+ _comment = error->myComment;
+ return error->IsOK();
+ }
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief return compute error
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr SMESH_Algo::GetComputeError() const
+{
+ return SMESH_ComputeError::New( _error, _comment, this );
+}
+
+//================================================================================
+/*!
+ * \brief initialize compute error
+ */
+//================================================================================
+
+void SMESH_Algo::InitComputeError()
+{
+ _error = COMPERR_OK;
+ _comment.clear();
+}
+
#include "SMESH_SMESH.hxx"
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
+#include "SMESH_Comment.hxx"
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
-#include <gp_XY.hxx>
+#include <GeomAbs_Shape.hxx>
#include <string>
#include <vector>
#include <list>
-#include <map>
class SMESH_Gen;
class SMESH_Mesh;
class SMESH_HypoFilter;
+class TopoDS_Vertex;
class TopoDS_Face;
class TopoDS_Shape;
class SMESHDS_Mesh;
class SMDS_MeshNode;
class SMESH_subMesh;
+class SMESH_MesherHelper;
+
class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis
{
* \param aMesh - the mesh
* \param aShape - the shape
* \retval bool - is a success
+ *
+ * Algorithms that !NeedDescretBoundary() || !OnlyUnaryInput() are
+ * to set SMESH_ComputeError returned by SMESH_submesh::GetComputeError()
+ * to report problematic subshapes
*/
virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0;
+ /*!
+ * \brief Computes mesh without geometry
+ * \param aMesh - the mesh
+ * \param aHelper - helper that must be used for adding elements to \aaMesh
+ * \retval bool - is a success
+ *
+ * The method is called if ( !aMesh->HasShapeToMesh() )
+ */
+ virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
+
/*!
* \brief Returns a list of compatible hypotheses used to mesh a shape
* \param aMesh - the mesh
const bool ignoreAuxiliary) const;
/*!
* \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
*
* Just return false as the algorithm does not hold parameters values
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh,
const TopoDS_Shape& theShape);
-
+ /*!
+ * \brief return compute error
+ */
+ SMESH_ComputeErrorPtr GetComputeError() const;
+ /*!
+ * \brief initialize compute error
+ */
+ void InitComputeError();
public:
// ==================================================================
bool NeedDescretBoundary() const { return _requireDescretBoundary; }
// 3 - is a Dim-1 mesh prerequisite
+ bool NeedShape() const { return _requireShape; }
+ // 4 - is shape existance required
+
public:
// ==================================================================
// Methods to track non hierarchical dependencies between submeshes
*/
virtual void SetEventListener(SMESH_subMesh* subMesh);
+ /*!
+ * \brief Allow algo to do something after persistent restoration
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+ virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+
public:
// ==================================================================
// Common algo utilities
*/
static double EdgeLength(const TopoDS_Edge & E);
+ /*!
+ * \brief Return continuity of two edges
+ * \param E1 - the 1st edge
+ * \param E2 - the 2nd edge
+ * \retval GeomAbs_Shape - regularity at the junction between E1 and E2
+ */
+ static GeomAbs_Shape Continuity(const TopoDS_Edge & E1,
+ const TopoDS_Edge & E2);
+
+ /*!
+ * \brief Return the node built on a vertex
+ * \param V - the vertex
+ * \param meshDS - mesh
+ * \retval const SMDS_MeshNode* - found node or NULL
+ */
+ static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V,
+ SMESHDS_Mesh* meshDS);
protected:
- bool _onlyUnaryInput;
- bool _requireDescretBoundary;
- std::vector<std::string> _compatibleHypothesis;
+
+ /*!
+ * \brief store error and comment and then return ( error == COMPERR_OK )
+ */
+ bool error(int error, const SMESH_Comment& comment = "");
+ /*!
+ * \brief To be used as error in previous method
+ */
+ SMESH_ComputeErrorName dfltErr() const { return COMPERR_ALGO_FAILED; }
+ /*!
+ * \brief store error and return error->IsOK()
+ */
+ bool error(SMESH_ComputeErrorPtr error);
+
+protected:
+
+ std::vector<std::string> _compatibleHypothesis;
std::list<const SMESHDS_Hypothesis *> _appliedHypList;
std::list<const SMESHDS_Hypothesis *> _usedHypList;
- // quadratic mesh creation required
+ bool _onlyUnaryInput;
+ bool _requireDescretBoundary;
+ bool _requireShape;
+
+ // quadratic mesh creation required,
+ // is usually set trough SMESH_MesherHelper::IsQuadraticSubMesh()
bool _quadraticMesh;
+
+ int _error; //!< SMESH_ComputeErrorName or anything algo specific
+ std::string _comment; //!< any text explaining what is wrong in Compute()
};
#endif
// Note: to compute params of a point on a face, it is enough to set
// TFace, TEdge's and points for that face only
+ // Note 2: curve adaptors need to have only Value(double), FirstParameter() and
+ // LastParameter() defined to be used by Block algoritms
+
class SMESH_EXPORT TEdge {
int myCoordInd;
double myFirst;
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+// File : SMESH_Comment.hxx
+// Created : Wed Mar 14 18:28:45 2007
+// Author : Edward AGAPOV (eap)
+// Module : SMESH
+// $Header:
+
+
+#ifndef SMESH_Comment_HeaderFile
+#define SMESH_Comment_HeaderFile
+
+# include <string>
+# include <sstream>
+
+using namespace std;
+
+/*!
+ * \brief Class to generate string from any type
+ */
+class SMESH_Comment : public string
+{
+ ostringstream _s ;
+
+public :
+
+ SMESH_Comment():string("") {}
+
+ SMESH_Comment(const SMESH_Comment& c):string() {
+ _s << c.c_str() ;
+ this->string::operator=( _s.str() );
+ }
+
+ template <class T>
+ SMESH_Comment( const T &anything ) {
+ _s << anything ;
+ this->string::operator=( _s.str() );
+ }
+
+ template <class T>
+ SMESH_Comment & operator<<( const T &anything ) {
+ _s << anything ;
+ this->string::operator=( _s.str() );
+ return *this ;
+ }
+};
+
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_Hypothesis.hxx
+// Author : Edward AGAPOV (eap)
+// Module : SMESH
+// $Header:
+
+#ifndef SMESH_ComputeError_HeaderFile
+#define SMESH_ComputeError_HeaderFile
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+class SMESH_Algo;
+struct SMESH_ComputeError;
+
+typedef boost::shared_ptr<SMESH_ComputeError> SMESH_ComputeErrorPtr;
+
+// =============================================================
+
+enum SMESH_ComputeErrorName
+{
+ // If you modify it, pls update SMESH_ComputeError::CommonName() below.
+ // Positive values are for algo specific errors
+ COMPERR_OK = -1,
+ COMPERR_BAD_INPUT_MESH = -2, //!< wrong mesh on lower submesh
+ COMPERR_STD_EXCEPTION = -3, //!< some std exception raised
+ COMPERR_OCC_EXCEPTION = -4, //!< OCC exception raised
+ COMPERR_SLM_EXCEPTION = -5, //!< SALOME exception raised
+ COMPERR_EXCEPTION = -6, //!< other exception raised
+ COMPERR_MEMORY_PB = -7, //!< std::bad_alloc exception
+ COMPERR_ALGO_FAILED = -8, //!< algo failed for some reason
+ COMPERR_BAD_SHAPE = -9 //!< bad geometry
+};
+
+// =============================================================
+/*!
+ * \brief Contains algorithm and description of occured error
+ */
+// =============================================================
+
+struct SMESH_ComputeError
+{
+ int myName; //!< SMESH_ComputeErrorName or anything algo specific
+ std::string myComment;
+ const SMESH_Algo* myAlgo;
+
+ static SMESH_ComputeErrorPtr New( int error = COMPERR_OK,
+ std::string comment = "",
+ const SMESH_Algo* algo = 0)
+ { return SMESH_ComputeErrorPtr( new SMESH_ComputeError( error, comment, algo )); }
+
+ SMESH_ComputeError(int error = COMPERR_OK,
+ std::string comment = "",
+ const SMESH_Algo* algo = 0)
+ :myName(error),myComment(comment),myAlgo(algo) {}
+
+ bool IsOK() { return myName == COMPERR_OK; }
+ bool IsCommon() { return myName < 0; }
+ inline std::string CommonName() const;
+
+};
+
+#define case2char(err) case err: return #err;
+
+std::string SMESH_ComputeError::CommonName() const
+{
+ switch( myName ) {
+ case2char(COMPERR_OK );
+ case2char(COMPERR_BAD_INPUT_MESH);
+ case2char(COMPERR_STD_EXCEPTION );
+ case2char(COMPERR_OCC_EXCEPTION );
+ case2char(COMPERR_SLM_EXCEPTION );
+ case2char(COMPERR_EXCEPTION );
+ case2char(COMPERR_MEMORY_PB );
+ case2char(COMPERR_ALGO_FAILED );
+ default:;
+ }
+ return "";
+}
+
+#endif
//=============================================================================
/*!
- *
+ * Compute a mesh
*/
//=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
MESSAGE("SMESH_Gen::Compute");
- // bool isDone = false;
- /*
- Algo : s'appuie ou non sur une geometrie
- Si geometrie:
- Vertex : rien à faire (range le point)
- Edge, Wire, collection d'edge et wire : 1D
- Face, Shell, collection de Face et Shells : 2D
- Solid, Collection de Solid : 3D
- */
- // *** corriger commentaires
- // check hypothesis associated to the mesh :
- // - only one algo : type compatible with the type of the shape
- // - hypothesis = compatible with algo
- // - check if hypothesis are applicable to this algo
- // - check contradictions within hypothesis
- // (test if enough hypothesis is done further)
bool ret = true;
-// if ( !CheckAlgoState( aMesh, aShape ))
-// {
-// INFOS( "ABORT MESHING: some algos or hypothesis are missing");
-// return false;
-// }
-
SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
- if ( sm->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
- return true; // already computed
-
// -----------------------------------------------------------------
// apply algos that do not require descretized boundaries, starting
// from the most complex shapes
// -----------------------------------------------------------------
- // map containing all subshapes in the order: vertices, edges, faces...
- const map<int, SMESH_subMesh*>& smMap = sm->DependsOn();
- map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
+ const bool includeSelf = true;
+ const bool complexShapeFirst = true;
- SMESH_subMesh* smToCompute = sm;
- while ( smToCompute )
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
+ complexShapeFirst);
+ while ( smIt->more() )
{
+ SMESH_subMesh* smToCompute = smIt->next();
+
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
if ( GetShapeDim( aSubShape ) < 1 ) break;
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
- if (algo && !algo->NeedDescretBoundary()) {
- if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
- ret = smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
- } else if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) {
- // JFA for PAL6524
- ret = false;
- } else {
- }
- }
- if (!ret)
- return false;
-
- // next subMesh
- if (revItSub != smMap.rend())
+ if (algo && !algo->NeedDescretBoundary())
{
- smToCompute = (*revItSub).second;
- revItSub++;
+ if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+
+ if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+ ret = false;;
}
- else
- smToCompute = 0;
}
// -----------------------------------------------
// mesh the rest subshapes starting from vertices
// -----------------------------------------------
-
- int i, nbSub = smMap.size();
- map<int, SMESH_subMesh*>::const_iterator itSub = smMap.begin();
- for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus <sm>
+ smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+ while ( smIt->more() )
{
- if ( itSub == smMap.end() )
- smToCompute = sm;
- else
- smToCompute = (itSub++)->second;
- if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) {
- if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
- ret = false;
- continue;
- }
- TopoDS_Shape subShape = smToCompute->GetSubShape();
- if ( subShape.ShapeType() != TopAbs_VERTEX )
- {
- if ( !smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE) )
- ret = false;
- }
- else
- {
- TopoDS_Vertex V1 = TopoDS::Vertex(subShape);
- gp_Pnt P1 = BRep_Tool::Pnt(V1);
- SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- SMDS_MeshNode * node = meshDS->AddNode(P1.X(), P1.Y(), P1.Z());
- if ( node ) { // san - increase robustness
- meshDS->SetNodeOnVertex(node, V1);
- smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
- }
- }
+ SMESH_subMesh* smToCompute = smIt->next();
+
+ if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+
+ if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+ ret = false;
}
MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
return ret;
}
-
//=======================================================================
//function : checkConformIgnoredAlgos
//purpose :
"> would produce not conform mesh: "
"<Not Conform Mesh Allowed> hypotesis is missing");
theErrors.push_back( SMESH_Gen::TAlgoStateError() );
- theErrors.back().Set( SMESH_Gen::NOT_CONFORM_MESH, algo, false );
+ theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
}
// sub-algos will be hidden by a local <algo>
INFOS( "ERROR: " << shapeDim << "D algorithm is missing" );
ret = false;
theErrors.push_back( SMESH_Gen::TAlgoStateError() );
- theErrors.back().Set( SMESH_Gen::MISSING_ALGO, shapeDim, true );
+ theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, shapeDim, true );
}
}
return ret;
bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
{
- SMESH_Gen::TAlgoStateErrorName errName = SMESH_Gen::MISSING_HYPO;
+ TAlgoStateErrorName errName = SMESH_Hypothesis::HYP_MISSING;
SMESH_Hypothesis::Hypothesis_Status status;
algo->CheckHypothesis( aMesh, aSubMesh->GetSubShape(), status );
if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) {
INFOS( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ")
<< "<" << algo->GetName() << "> has a bad parameter value");
- errName = SMESH_Gen::BAD_PARAM_VALUE;
+ errName = SMESH_Hypothesis::HYP_BAD_PARAMETER;
} else {
INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
<< "<" << algo->GetName() << "> misses some hypothesis");
// --------------------------------------------------------
- // find a global algo possibly hidding sub-algos
+ // find a global algo possibly hiding sub-algos
int dim;
const SMESH_Algo* aGlobIgnoAlgo = 0;
for (dim = 3; dim > 0; dim--)
aCheckedMap.clear();
smToCheck = sm;
revItSub = smMap.rbegin();
- bool checkNoAlgo = (bool) aTopAlgoDim;
+ bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false;
bool globalChecked[] = { false, false, false, false };
// loop on theShape and its sub-shapes
ret = false;
INFOS( "None algorithm attached" );
theErrors.push_back( TAlgoStateError() );
- theErrors.back().Set( MISSING_ALGO, 1, true );
+ theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
}
return ret;
#include "Utils_SALOME_Exception.hxx"
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
#include "SMESH_Algo.hxx"
+#include "SMESH_0D_Algo.hxx"
#include "SMESH_1D_Algo.hxx"
#include "SMESH_2D_Algo.hxx"
#include "SMESH_3D_Algo.hxx"
#include <map>
+typedef SMESH_Hypothesis::Hypothesis_Status TAlgoStateErrorName;
typedef struct studyContextStruct
{
- std::map < int, SMESH_Hypothesis * >mapHypothesis;
- std::map < int, SMESH_Mesh * >mapMesh;
- SMESHDS_Document * myDocument;
+ std::map < int, SMESH_Hypothesis * >mapHypothesis;
+ std::map < int, SMESH_Mesh * >mapMesh;
+ SMESHDS_Document * myDocument;
} StudyContextStruct;
class SMESH_EXPORT SMESH_Gen
SMESH_Gen();
~SMESH_Gen();
-// SMESH_Hypothesis *CreateHypothesis(const char *anHyp, int studyId)
-// throw(SALOME_Exception);
SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode)
throw(SALOME_Exception);
+
bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// if Compute() would fail because of some algo bad state
- enum TAlgoStateErrorName { NONE=0,
- MISSING_ALGO,
- MISSING_HYPO,
- NOT_CONFORM_MESH,
- BAD_PARAM_VALUE };
struct TAlgoStateError
{
TAlgoStateErrorName _name;
int _algoDim;
bool _isGlobalAlgo;
- TAlgoStateError(): _algoDim(0),_algo(0),_name(NONE) {}
+ TAlgoStateError(): _algoDim(0),_algo(0),_name(SMESH_Hypothesis::HYP_OK) {}
void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal)
{ _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; }
void Set(TAlgoStateErrorName name, const int algoDim, bool isGlobal)
// if Compute() would fail because of some algo bad state
// theErrors list contains problems description
-
StudyContextStruct *GetStudyContext(int studyId);
static int GetShapeDim(const TopAbs_ShapeEnum & aShapeType);
int GetANewId();
std::map < int, SMESH_Algo * >_mapAlgo;
+ std::map < int, SMESH_0D_Algo * >_map0D_Algo;
std::map < int, SMESH_1D_Algo * >_map1D_Algo;
std::map < int, SMESH_2D_Algo * >_map2D_Algo;
std::map < int, SMESH_3D_Algo * >_map3D_Algo;
{
SMESH_Mesh* mesh = (*itm).second;
mesh->NotifySubMeshesHypothesisModification( this );
-// const list<SMESH_subMesh*>& subMeshes =
-// mesh->GetSubMeshUsingHypothesis(this);
-
-// //for all subMeshes using hypothesis
-
-// list<SMESH_subMesh*>::const_iterator its;
-// for (its = subMeshes.begin(); its != subMeshes.end(); its++)
-// (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
}
}
const char* SMESH_Hypothesis::GetLibName() const
{
-// MESSAGE("SMESHDS_Hypothesis::GetLibName");
-// SCRUTE(_LibName);
-// SCRUTE(&_LibName);
return _libName.c_str();
}
void SMESH_Hypothesis::SetLibName(const char* theLibName)
{
-// MESSAGE("SMESHDS_Hypothesis::SetLibName");
_libName = string(theLibName);
}
public:
enum Hypothesis_Status // in the order of severity
{
- HYP_OK,
+ HYP_OK = 0,
HYP_MISSING, // algo misses a hypothesis
HYP_CONCURENT, // several applicable hypotheses
HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
+ HYP_HIDDEN_ALGO, // an algo is hidden by an upper dim algo generating all-dim elements
+ HYP_HIDING_ALGO, // an algo hides lower dim algos by generating all-dim elements
HYP_UNKNOWN_FATAL,// --- all statuses below should be considered as fatal
// for Add/RemoveHypothesis operations
HYP_INCOMPATIBLE, // hypothesis does not fit algo
* dimention can be assigned to the shape
*/
virtual bool IsAuxiliary() const
- { return GetType() == PARAM_ALGO && _param_algo_dim <= 0; }
+ { return GetType() == PARAM_ALGO && _param_algo_dim < 0; }
protected:
SMESH_Gen* _gen;
#include "DriverSTL_R_SMDS_Mesh.h"
#include <BRepTools_WireExplorer.hxx>
+#include <BRepPrimAPI_MakeBox.hxx>
#include <BRep_Builder.hxx>
#include <gp_Pnt.hxx>
*/
//=============================================================================
-SMESH_Mesh::SMESH_Mesh(int theLocalId,
- int theStudyId,
- SMESH_Gen* theGen,
- bool theIsEmbeddedMode,
+SMESH_Mesh::SMESH_Mesh(int theLocalId,
+ int theStudyId,
+ SMESH_Gen* theGen,
+ bool theIsEmbeddedMode,
SMESHDS_Document* theDocument):
_groupId( 0 )
{
- INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
- _id = theLocalId;
- _studyId = theStudyId;
- _gen = theGen;
- _myDocument = theDocument;
- _idDoc = theDocument->NewMesh(theIsEmbeddedMode);
- _myMeshDS = theDocument->GetMesh(_idDoc);
+ MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
+ _id = theLocalId;
+ _studyId = theStudyId;
+ _gen = theGen;
+ _myDocument = theDocument;
+ _idDoc = theDocument->NewMesh(theIsEmbeddedMode);
+ _myMeshDS = theDocument->GetMesh(_idDoc);
_isShapeToMesh = false;
+ _myMeshDS->ShapeToMesh( PseudoShape() );
}
//=============================================================================
//=============================================================================
/*!
- *
+ * \brief Set geometry to be meshed
*/
//=============================================================================
{
if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
- if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() )
+ if ( !aShape.IsNull() && _isShapeToMesh )
+ throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+
+ // clear current data
+ if ( !_myMeshDS->ShapeToMesh().IsNull() )
{
// removal of a shape to mesh, delete objects referring to sub-shapes:
// - sub-meshes
else
i_gr++;
}
+ _mapAncestors.Clear();
_mapPropagationChains.Clear();
+
+ // clear SMESHDS
+ TopoDS_Shape aNullShape;
+ _myMeshDS->ShapeToMesh( aNullShape );
}
- else
+
+ // set a new geometry
+ if ( !aShape.IsNull() )
{
- if (_isShapeToMesh)
- throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+ _myMeshDS->ShapeToMesh(aShape);
+ _isShapeToMesh = true;
+
+ // fill _mapAncestors
+ int desType, ancType;
+ for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
+ for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
+ TopExp::MapShapesAndAncestors ( aShape,
+ (TopAbs_ShapeEnum) desType,
+ (TopAbs_ShapeEnum) ancType,
+ _mapAncestors );
}
- _isShapeToMesh = true;
- _myMeshDS->ShapeToMesh(aShape);
-
- // fill _mapAncestors
- _mapAncestors.Clear();
- int desType, ancType;
- for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
- for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
- TopExp::MapShapesAndAncestors ( aShape,
- (TopAbs_ShapeEnum) desType,
- (TopAbs_ShapeEnum) ancType,
- _mapAncestors );
-
- // NRI : 24/02/03
- //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS
+}
+
+//=======================================================================
+/*!
+ * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+ */
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
+{
+ return _myMeshDS->ShapeToMesh();
+}
+
+//=======================================================================
+/*!
+ * \brief Return a solid which is returned by GetShapeToMesh() if
+ * a real geometry to be meshed was not set
+ */
+//=======================================================================
+
+const TopoDS_Solid& SMESH_Mesh::PseudoShape()
+{
+ static TopoDS_Solid aSolid;
+ if ( aSolid.IsNull() )
+ {
+ aSolid = BRepPrimAPI_MakeBox(1,1,1);
+ }
+ return aSolid;
}
//=======================================================================
// check concurent hypotheses on ansestors
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
{
- const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
- map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
- for ( ; smIt != smMap.end(); smIt++ ) {
- if ( smIt->second->IsApplicableHypotesis( anHyp )) {
- ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+ SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+ while ( smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ if ( sm->IsApplicableHypotesis( anHyp )) {
+ ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
if (ret2 > ret) {
ret = ret2;
break;
// check concurent hypotheses on ansestors
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
{
- const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
- map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
- for ( ; smIt != smMap.end(); smIt++ ) {
- if ( smIt->second->IsApplicableHypotesis( anHyp )) {
- ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+ SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+ while ( smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ if ( sm->IsApplicableHypotesis( anHyp )) {
+ ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
if (ret2 > ret) {
ret = ret2;
break;
*/
//=============================================================================
-SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
-{
- return _myMeshDS;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
const list<const SMESHDS_Hypothesis*>&
SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
throw(SALOME_Exception)
_myMeshDS->GetScript()->Clear();
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-int SMESH_Mesh::GetId()
-{
- if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId");
- return _id;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Gen *SMESH_Mesh::GetGen()
-{
- return _gen;
-}
-
//=============================================================================
/*!
* Get or Create the SMESH_subMesh object implementation
//purpose : Say all submeshes using theChangedHyp that it has been modified
//=======================================================================
-void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp)
+void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
{
Unexpect aCatch(SalomeException);
- const SMESH_Hypothesis* hyp = cSMESH_Hyp(theChangedHyp);
-
const SMESH_Algo *foundAlgo = 0;
SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() );
SMESH_HypoFilter compatibleHypoKind;
if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
{
- aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
+ aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+ const_cast< SMESH_Hypothesis*>( hyp ));
if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape ))
CleanMeshOnPropagationChain( aSubShape );
class TopTools_ListOfShape;
class SMESH_subMesh;
class SMESH_HypoFilter;
+class TopoDS_Solid;
-//typedef NMTTools_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain;
typedef SMESH_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain;
class SMESH_EXPORT SMESH_Mesh
{
- SMESH_Mesh();
- SMESH_Mesh(const SMESH_Mesh&);
public:
- SMESH_Mesh(int theLocalId,
- int theStudyId,
- SMESH_Gen* theGen,
- bool theIsEmbeddedMode,
+ SMESH_Mesh(int theLocalId,
+ int theStudyId,
+ SMESH_Gen* theGen,
+ bool theIsEmbeddedMode,
SMESHDS_Document* theDocument);
virtual ~SMESH_Mesh();
+ /*!
+ * \brief Set geometry to be meshed
+ */
void ShapeToMesh(const TopoDS_Shape & aShape);
-
+ /*!
+ * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+ */
+ TopoDS_Shape GetShapeToMesh() const;
+ /*!
+ * \brief Return true if there is a geometry to be meshed, not PseudoShape()
+ */
+ bool HasShapeToMesh() const { return _isShapeToMesh; }
+ /*!
+ * \brief Return a solid which is returned by GetShapeToMesh() if
+ * a real geometry to be meshed was not set
+ */
+ static const TopoDS_Solid& PseudoShape();
+
+
int UNVToMesh(const char* theFileName);
/*!
* consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
void ClearLog() throw(SALOME_Exception);
- int GetId();
+ int GetId() { return _id; }
- SMESHDS_Mesh * GetMeshDS();
+ SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; }
- SMESH_Gen *GetGen();
+ SMESH_Gen *GetGen() { return _gen; }
SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape)
throw(SALOME_Exception);
void CleanMeshOnPropagationChain(const TopoDS_Shape& theMainEdge);
//
-private:
+protected:
int _id; // id given by creator (unique within the creator instance)
int _studyId;
int _idDoc; // id given by SMESHDS_Document
TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
IndexedMapOfChain _mapPropagationChains; // Propagation hypothesis management
+
+protected:
+ SMESH_Mesh() {};
+ SMESH_Mesh(const SMESH_Mesh&) {};
};
#endif
#include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_OctreeNode.hxx"
#include "utilities.h"
#include <TopoDS_Face.hxx>
#include <map>
+#include <set>
+
+#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
using namespace std;
using namespace SMESH::Controls;
typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeListMapItr> > TElemOfVecOfNnlmiMap;
//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> > TElemOfVecOfMapNodesMap;
+struct TNodeXYZ : public gp_XYZ {
+ TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
+};
+
typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
+/*!
+ * \brief A sorted pair of nodes
+ */
+struct TLink: public NLink
+{
+ TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+ { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+ TLink(const NLink& link ):NLink( link )
+ { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+};
+
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
{
}
+//=======================================================================
+/*!
+ * \brief Add element
+ */
+//=======================================================================
+
+SMDS_MeshElement*
+SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
+ const SMDSAbs_ElementType type,
+ const bool isPoly,
+ const int ID)
+{
+ SMDS_MeshElement* e = 0;
+ int nbnode = node.size();
+ SMESHDS_Mesh* mesh = GetMeshDS();
+ switch ( type ) {
+ case SMDSAbs_Edge:
+ if ( nbnode == 2 )
+ if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+ else e = mesh->AddEdge (node[0], node[1] );
+ else if ( nbnode == 3 )
+ if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+ else e = mesh->AddEdge (node[0], node[1], node[2] );
+ break;
+ case SMDSAbs_Face:
+ if ( !isPoly ) {
+ if (nbnode == 3)
+ if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2] );
+ else if (nbnode == 4)
+ if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3] );
+ else if (nbnode == 6)
+ if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3],
+ node[4], node[5] );
+ else if (nbnode == 8)
+ if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7] );
+ } else {
+ if ( ID ) e = mesh->AddPolygonalFaceWithID(node, ID);
+ else e = mesh->AddPolygonalFace (node );
+ }
+ break;
+ case SMDSAbs_Volume:
+ if ( !isPoly ) {
+ if (nbnode == 4)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3] );
+ else if (nbnode == 5)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4] );
+ else if (nbnode == 6)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5] );
+ else if (nbnode == 8)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7] );
+ else if (nbnode == 10)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9] );
+ else if (nbnode == 13)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12] );
+ else if (nbnode == 15)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14] );
+ else if (nbnode == 20)
+ if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],node[15],
+ node[16],node[17],node[18],node[19],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],node[15],
+ node[16],node[17],node[18],node[19] );
+ }
+ }
+ return e;
+}
+
+//=======================================================================
+/*!
+ * \brief Add element
+ */
+//=======================================================================
+
+SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> & nodeIDs,
+ const SMDSAbs_ElementType type,
+ const bool isPoly,
+ const int ID)
+{
+ vector<const SMDS_MeshNode*> nodes;
+ nodes.reserve( nodeIDs.size() );
+ vector<int>::const_iterator id = nodeIDs.begin();
+ while ( id != nodeIDs.end() ) {
+ if ( const SMDS_MeshNode* node = GetMeshDS()->FindNode( *id++ ))
+ nodes.push_back( node );
+ else
+ return 0;
+ }
+ return AddElement( nodes, type, isPoly, ID );
+}
+
//=======================================================================
//function : Remove
//purpose : Remove a node or an element.
//=======================================================================
//function : IsMedium
-//purpose :
+//purpose :
//=======================================================================
bool SMESH_MeshEditor::IsMedium(const SMDS_MeshNode* node,
const SMDSAbs_ElementType typeToCheck)
{
bool isMedium = false;
- SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
- while (it->more()) {
+ SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(typeToCheck);
+ while (it->more() && !isMedium ) {
const SMDS_MeshElement* elem = it->next();
isMedium = elem->IsMediumNode(node);
- if ( typeToCheck == SMDSAbs_All || elem->GetType() == typeToCheck )
- break;
}
return isMedium;
}
ShiftNodesQuadTria(N2);
}
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
return true;
}
SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
while ( it->more() ) {
aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-
+
if ( i > 2 ) // theTria2
// find same node of theTria1
for ( int j = 0; j < 3; j++ )
if ( i == 6 && it->more() )
return false; // theTria2 is not a triangle
}
-
+
// find indices of 1,2 and of A,B in theTria1
int iA = 0, iB = 0, i1 = 0, i2 = 0;
for ( i = 0; i < 6; i++ ) {
aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
//MESSAGE( theTria1 << theTria2 );
-
+
GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
-
+
//MESSAGE( theTria1 << theTria2 );
return true;
-
+
} // end if(F1 && F2)
// check case of quadratic faces
// 5
// 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
// | /| theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
- // | / |
+ // | / |
// 7 + + + 6
// | /9 |
// |/ |
- // 4 +--+--+ 3
+ // 4 +--+--+ 3
// 8
-
+
const SMDS_MeshNode* N1 [6];
const SMDS_MeshNode* N2 [6];
if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2))
return false;
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* N1new [6];
theTria1 = theTria2 = 0;
set< const SMDS_MeshElement* > emap;
- SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator(SMDSAbs_Face);
while (it->more()) {
const SMDS_MeshElement* elem = it->next();
- if ( elem->GetType() == SMDSAbs_Face && elem->NbNodes() == 3 )
+ if ( elem->NbNodes() == 3 )
emap.insert( elem );
}
- it = theNode2->GetInverseElementIterator();
+ it = theNode2->GetInverseElementIterator(SMDSAbs_Face);
while (it->more()) {
const SMDS_MeshElement* elem = it->next();
- if ( elem->GetType() == SMDSAbs_Face &&
- emap.find( elem ) != emap.end() )
+ if ( emap.find( elem ) != emap.end() )
if ( theTria1 ) {
// theTria1 must be element with minimum ID
if( theTria1->GetID() < elem->GetID() ) {
else if ( aNodes2[ i ] != theNode1 )
i2 = i; // node 2
}
-
+
// nodes 1 and 2 should not be the same
if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
return false;
GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
//MESSAGE( tr1 << tr2 );
-
+
return true;
}
const SMDS_MeshNode* n4 = 0;
SMDS_ElemIteratorPtr it = tr2->nodesIterator();
int i=0;
- //while ( !n4 && it->more() ) {
while ( !n4 && i<3 ) {
- const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+ const SMDS_MeshNode * n = cast2Node( it->next() );
i++;
bool isDiag = ( n == theNode1 || n == theNode2 );
if ( !isDiag )
int iNode = 0, iFirstDiag = -1;
it = tr1->nodesIterator();
i=0;
- //while ( it->more() ) {
while ( i<3 ) {
- const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+ const SMDS_MeshNode * n = cast2Node( it->next() );
i++;
bool isDiag = ( n == theNode1 || n == theNode2 );
if ( isDiag ) {
// 5
// 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
// | /| tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
- // | / |
+ // | / |
// 7 + + + 6
// | /9 |
// |/ |
- // 4 +--+--+ 3
+ // 4 +--+--+ 3
// 8
-
+
const SMDS_MeshNode* N1 [6];
const SMDS_MeshNode* N2 [6];
if(!GetNodesFromTwoTria(tr1,tr2,N1,N2))
return false;
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
for (int iface = 1; iface <= nbFaces; iface++) {
int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
quantities[iface - 1] = nbFaceNodes;
-
+
for (inode = nbFaceNodes; inode >= 1; inode--) {
const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
poly_nodes.push_back(curNode);
}
}
-
+
return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
}
// theCrit is used to select a diagonal to cut
//=======================================================================
-bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> & theElems,
+bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
SMESH::Controls::NumericalFunctorPtr theCrit)
{
myLastCreatedElems.Clear();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
- map<int, const SMDS_MeshElement * >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 ))
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
- }
+ }
}
// find middle point for (0,1,2,3)
// and create a node in this point;
SMESHDS_Mesh * aMesh)
{
const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
- if (!groups.empty())
+ if (!groups.empty())
{
set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
- for (; GrIt != groups.end(); GrIt++)
+ for (; GrIt != groups.end(); GrIt++)
{
SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
if (!grp || grp->IsEmpty()) continue;
// theCrit is used to select a diagonal to cut
//=======================================================================
-bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
- const bool the13Diag)
+bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
+ const bool the13Diag)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
- map<int, const SMDS_MeshElement * >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
inFaceNode = aNodes[ i-1 ];
- }
+ }
}
// find middle point for (0,1,2,3)
// fusion is still performed.
//=======================================================================
-bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> & theElems,
+bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
SMESH::Controls::NumericalFunctorPtr theCrit,
const double theMaxAngle)
{
return false;
SMESHDS_Mesh * aMesh = GetMeshDS();
- //LinkID_Gen aLinkID_Gen( aMesh );
// Prepare data for algo: build
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
- //map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
- //map< long, list< const SMDS_MeshElement* > >::iterator itLE;
- //map< const SMDS_MeshElement*, set< long > > mapEl_setLi;
- //map< const SMDS_MeshElement*, set< long > >::iterator itEL;
-
- map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl;
- map< NLink, list< const SMDS_MeshElement* > >::iterator itLE;
- map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi;
- map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
+ map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+ map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+ map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi;
+ map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
- map<int,const SMDS_MeshElement*>::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
- //if ( !elem || elem->NbNodes() != 3 )
- // continue;
+ const SMDS_MeshElement* elem = *itElem;
if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic());
if(!IsTria) continue;
const SMDS_MeshNode* aNodes [4];
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0;
- //while ( itN->more() )
while ( i<3 )
- aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
- ASSERT( i == 3 );
+ aNodes[ i++ ] = cast2Node( itN->next() );
aNodes[ 3 ] = aNodes[ 0 ];
// fill maps
for ( i = 0; i < 3; i++ ) {
- //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
- NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ),
- ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] ));
+ TLink link( aNodes[i], aNodes[i+1] );
// check if elements sharing a link can be fused
- //itLE = mapLi_listEl.find( linkID );
itLE = mapLi_listEl.find( link );
if ( itLE != mapLi_listEl.end() ) {
if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
(*itLE).second.push_back( elem );
}
else {
- //mapLi_listEl[ linkID ].push_back( elem );
mapLi_listEl[ link ].push_back( elem );
}
- //mapEl_setLi [ elem ].insert( linkID );
mapEl_setLi [ elem ].insert( link );
}
}
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
- //long link = (*itLE).first;
- NLink link = (*itLE).first;
+ TLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
while ( ! mapEl_setLi.empty() ) {
// Look for the start element:
// the element having the least nb of shared links
-
const SMDS_MeshElement* startElem = 0;
int minNbLinks = 4;
for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) {
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
- //list< long > startLinks;
- list< NLink > startLinks;
+ list< TLink > startLinks;
while ( startElem || !startLinks.empty() ) {
while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
- //long linkId = startLinks.front();
- NLink linkId = startLinks.front();
+ TLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
if ( itLE != mapLi_listEl.end() ) {
if ( startElem ) {
// Get candidates to be fused
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
- //long link12, link13;
- NLink link12, link13;
+ const TLink *link12, *link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
- //set< long >& setLi = mapEl_setLi[ tr1 ];
- set< NLink >& setLi = mapEl_setLi[ tr1 ];
+ set< TLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
- //set< long >::iterator itLi;
- set< NLink >::iterator itLi;
- for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) {
- //long linkID = (*itLi);
- NLink linkID = (*itLi);
- itLE = mapLi_listEl.find( linkID );
+ set< TLink >::iterator itLi;
+ for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
+ {
+ const TLink & link = (*itLi);
+ itLE = mapLi_listEl.find( link );
if ( itLE == mapLi_listEl.end() )
continue;
continue;
if ( tr2 ) {
tr3 = elem;
- link13 = linkID;
+ link13 = &link;
}
else {
tr2 = elem;
- link12 = linkID;
+ link12 = &link;
}
// add other links of elem to list of links to re-start from
- //set< long >& links = mapEl_setLi[ elem ];
- //set< long >::iterator it;
- set< NLink >& links = mapEl_setLi[ elem ];
- set< NLink >::iterator it;
+ set< TLink >& links = mapEl_setLi[ elem ];
+ set< TLink >::iterator it;
for ( it = links.begin(); it != links.end(); it++ ) {
- //long linkID2 = (*it);
- NLink linkID2 = (*it);
- if ( linkID2 != linkID )
- startLinks.push_back( linkID2 );
+ const TLink& link2 = (*it);
+ if ( link2 != link )
+ startLinks.push_back( link2 );
}
}
// Get nodes of possible quadrangles
const SMDS_MeshNode *n12 [4], *n13 [4];
bool Ok12 = false, Ok13 = false;
- //const SMDS_MeshNode *linkNode1, *linkNode2;
const SMDS_MeshNode *linkNode1, *linkNode2;
if(tr2) {
- //const SMDS_MeshNode *linkNode1 = link12.first;
- //const SMDS_MeshNode *linkNode2 = link12.second;
- linkNode1 = link12.first;
- linkNode2 = link12.second;
- //if ( tr2 &&
- // aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
- // getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
- // Ok12 = true;
+ linkNode1 = link12->first;
+ linkNode2 = link12->second;
if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
Ok12 = true;
}
if(tr3) {
- linkNode1 = link13.first;
- linkNode2 = link13.second;
- //if ( tr3 &&
- // aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
- // getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
- // Ok13 = true;
+ linkNode1 = link13->first;
+ linkNode2 = link13->second;
if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
Ok13 = true;
}
mapEl_setLi.erase( tr1 );
if ( Ok12 ) {
mapEl_setLi.erase( tr2 );
- mapLi_listEl.erase( link12 );
+ mapLi_listEl.erase( *link12 );
if(tr1->NbNodes()==3) {
if( tr1->GetID() < tr2->GetID() ) {
aMesh->ChangeElementNodes( tr1, n12, 4 );
const SMDS_MeshNode* N2 [6];
GetNodesFromTwoTria(tr1,tr2,N1,N2);
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
aNodes[0] = N1[0];
}
else if ( Ok13 ) {
mapEl_setLi.erase( tr3 );
- mapLi_listEl.erase( link13 );
+ mapLi_listEl.erase( *link13 );
if(tr1->NbNodes()==3) {
if( tr1->GetID() < tr2->GetID() ) {
aMesh->ChangeElementNodes( tr1, n13, 4 );
const SMDS_MeshNode* N2 [6];
GetNodesFromTwoTria(tr1,tr3,N1,N2);
// now we receive following N1 and N2 (using numeration as above image)
- // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
// i.e. first nodes from both arrays determ new diagonal
const SMDS_MeshNode* aNodes[8];
aNodes[0] = N1[0];
return true;
}*/
+//================================================================================
+/*!
+ * \brief Return nodes linked to the given one
+ * \param theNode - the node
+ * \param linkedNodes - the found nodes
+ * \param type - the type of elements to check
+ *
+ * Medium nodes are ignored
+ */
+//================================================================================
+
+void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode,
+ TIDSortedElemSet & linkedNodes,
+ SMDSAbs_ElementType type )
+{
+ SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(type);
+ while ( elemIt->more() )
+ {
+ const SMDS_MeshElement* elem = elemIt->next();
+ SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+ if ( elem->GetType() == SMDSAbs_Volume )
+ {
+ SMDS_VolumeTool vol( elem );
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = cast2Node( nodeIt->next() );
+ if ( theNode != n && vol.IsLinked( theNode, n ))
+ linkedNodes.insert( n );
+ }
+ }
+ else
+ {
+ for ( int i = 0; nodeIt->more(); ++i ) {
+ const SMDS_MeshNode* n = cast2Node( nodeIt->next() );
+ if ( n == theNode ) {
+ int iBefore = i - 1;
+ int iAfter = i + 1;
+ if ( elem->IsQuadratic() ) {
+ int nb = elem->NbNodes() / 2;
+ iAfter = SMESH_MesherHelper::WrapIndex( iAfter, nb );
+ iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb );
+ }
+ linkedNodes.insert( elem->GetNode( iAfter ));
+ linkedNodes.insert( elem->GetNode( iBefore ));
+ }
+ }
+ }
+ }
+}
+
//=======================================================================
//function : laplacianSmooth
//purpose : pulls theNode toward the center of surrounding nodes directly
{
// find surrounding nodes
- set< const SMDS_MeshNode* > nodeSet;
- SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
- while ( elemIt->more() )
- {
- const SMDS_MeshElement* elem = elemIt->next();
- if ( elem->GetType() != SMDSAbs_Face )
- continue;
-
- for ( int i = 0; i < elem->NbNodes(); ++i ) {
- if ( elem->GetNode( i ) == theNode ) {
- // add linked nodes
- int iBefore = i - 1;
- int iAfter = i + 1;
- if ( elem->IsQuadratic() ) {
- int nbCorners = elem->NbNodes() / 2;
- if ( iAfter >= nbCorners )
- iAfter = 0; // elem->GetNode() wraps index
- if ( iBefore == -1 )
- iBefore = nbCorners - 1;
- }
- nodeSet.insert( elem->GetNode( iAfter ));
- nodeSet.insert( elem->GetNode( iBefore ));
- break;
- }
- }
- }
+ TIDSortedElemSet nodeSet;
+ SMESH_MeshEditor::GetLinkedNodes( theNode, nodeSet, SMDSAbs_Face );
// compute new coodrs
double coord[] = { 0., 0., 0. };
- set< const SMDS_MeshNode* >::iterator nodeSetIt = nodeSet.begin();
+ TIDSortedElemSet::iterator nodeSetIt = nodeSet.begin();
for ( ; nodeSetIt != nodeSet.end(); nodeSetIt++ ) {
- const SMDS_MeshNode* node = (*nodeSetIt);
+ const SMDS_MeshNode* node = cast2Node(*nodeSetIt);
if ( theSurface.IsNull() ) { // smooth in 3D
coord[0] += node->X();
coord[1] += node->Y();
// compute new XYZ
- SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(SMDSAbs_Face);
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
- if ( elem->GetType() != SMDSAbs_Face )
- continue;
nbElems++;
gp_XYZ elemCenter(0.,0.,0.);
// on edges and boundary nodes are always fixed.
//=======================================================================
-void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
- set<const SMDS_MeshNode*> & theFixedNodes,
- const SmoothMethod theSmoothMethod,
- const int theNbIterations,
- double theTgtAspectRatio,
- const bool the2D)
+void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
+ set<const SMDS_MeshNode*> & theFixedNodes,
+ const SmoothMethod theSmoothMethod,
+ const int theNbIterations,
+ double theTgtAspectRatio,
+ const bool the2D)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
while ( fIt->more() ) {
const SMDS_MeshElement* face = fIt->next();
- theElems.insert( make_pair(face->GetID(),face) );
+ theElems.insert( face );
}
}
// get all face ids theElems are on
set< int > faceIdSet;
- map<int, const SMDS_MeshElement* >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
if ( the2D )
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- int fId = FindShape( (*itElem).second );
+ int fId = FindShape( *itElem );
// check that corresponding submesh exists and a shape is face
if (fId &&
faceIdSet.find( fId ) == faceIdSet.end() &&
if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
break; // all elements found
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
( faceSubMesh && !faceSubMesh->Contains( elem ))) {
++itElem;
{
// check if all faces around the node are on faceSubMesh
// because a node on edge may be bound to face
- SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
bool all = true;
if ( faceSubMesh ) {
while ( eIt->more() && all ) {
const SMDS_MeshElement* e = eIt->next();
- if ( e->GetType() == SMDSAbs_Face )
- all = faceSubMesh->Contains( e );
+ all = faceSubMesh->Contains( e );
}
}
if ( all )
if ( uvMap.find( node ) == uvMap.end() )
uvCheckNodes.push_back( node );
// add nodes of elems sharing node
-// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
// while ( eIt->more() ) {
// const SMDS_MeshElement* e = eIt->next();
-// if ( e != elem && e->GetType() == SMDSAbs_Face ) {
+// if ( e != elem ) {
// SMDS_ElemIteratorPtr nIt = e->nodesIterator();
// while ( nIt->more() ) {
// const SMDS_MeshNode* n =
uvMap2[ nSeam ] = &listUV.back();
// collect movable nodes linked to ones on seam in nodesNearSeam
- SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator(SMDSAbs_Face);
while ( eIt->more() ) {
const SMDS_MeshElement* e = eIt->next();
- if ( e->GetType() != SMDSAbs_Face )
- continue;
int nbUseMap1 = 0, nbUseMap2 = 0;
SMDS_ElemIteratorPtr nIt = e->nodesIterator();
int nn = 0, nbn = e->NbNodes();
gp_XY uv2 = helper.GetNodeUV( face, Ns[i+2], Ns[i] );
gp_XY uv = ( uv1 + uv2 ) / 2.;
gp_Pnt xyz = surface->Value( uv.X(), uv.Y() );
- x = xyz.X(); y = xyz.Y(); z = xyz.Z();
+ x = xyz.X(); y = xyz.Y(); z = xyz.Z();
}
else {
x = (Ns[i]->X() + Ns[i+2]->X())/2;
}
}
}
-
+
} // loop on face ids
}
// Loop on elem nodes:
// find new nodes and detect same nodes indices
int nbNodes = elem->NbNodes();
+ //---PR
//list<const SMDS_MeshNode*>::const_iterator itNN[ nbNodes ];
vector<list<const SMDS_MeshNode*>::const_iterator> itNN( nbNodes );
+ itNN.reserve(nbNodes);
+ //---PR
//const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ];
vector<const SMDS_MeshNode*> prevNod( nbNodes );
vector<const SMDS_MeshNode*> nextNod( nbNodes );
if ( nbSame == 0 ) // --- hexahedron
aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
-
+
else if ( nbSame == 1 ) { // --- pyramid + pentahedron
aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
// realized for extrusion only
//vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
//vector<int> quantities (nbNodes + 2);
-
+
//quantities[0] = nbNodes; // bottom of prism
//for (int inode = 0; inode < nbNodes; inode++) {
// polyedre_nodes[inode] = prevNod[inode];
//for (int inode = 0; inode < nbNodes; inode++) {
// polyedre_nodes[nbNodes + inode] = nextNod[inode];
//}
-
+
//for (int iface = 0; iface < nbNodes; iface++) {
// quantities[iface + 2] = 4;
// int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
//purpose : create 1D and 2D elements around swept elements
//=======================================================================
-static void makeWalls (SMESHDS_Mesh* aMesh,
- TNodeOfNodeListMap & mapNewNodes,
- TElemOfElemListMap & newElemsMap,
- TElemOfVecOfNnlmiMap & elemNewNodesMap,
- map<int,const SMDS_MeshElement*>& elemSet,
- const int nbSteps,
+static void makeWalls (SMESHDS_Mesh* aMesh,
+ TNodeOfNodeListMap & mapNewNodes,
+ TElemOfElemListMap & newElemsMap,
+ TElemOfVecOfNnlmiMap & elemNewNodesMap,
+ TIDSortedElemSet& elemSet,
+ const int nbSteps,
SMESH_SequenceOfElemPtr& myLastCreatedElems)
{
ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
nbInitElems = 0;
highType = type;
}
- if ( elemSet.find(el->GetID()) != elemSet.end() )
+ if ( elemSet.find(el) != elemSet.end() )
nbInitElems++;
}
if ( nbInitElems < 2 ) {
bool hasFreeLinks = false;
- map<int,const SMDS_MeshElement*> avoidSet;
- avoidSet.insert( make_pair(elem->GetID(),elem) );
+ TIDSortedElemSet avoidSet;
+ avoidSet.insert( elem );
set<const SMDS_MeshNode*> aFaceLastNodes;
int iNode, nbNodes = vecNewNodes.size();
//purpose :
//=======================================================================
-void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems,
- const gp_Ax1& theAxis,
- const double theAngle,
- const int theNbSteps,
- const double theTol)
+void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
+ const gp_Ax1& theAxis,
+ const double theAngle,
+ const int theNbSteps,
+ const double theTol,
+ const bool theMakeWalls)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
TElemOfElemListMap newElemsMap;
// loop on theElems
- map<int, const SMDS_MeshElement* >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
- if ( !elem )
+ const SMDS_MeshElement* elem = *itElem;
+ if ( !elem || elem->GetType() == SMDSAbs_Volume )
continue;
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
newNodesItVec.reserve( elem->NbNodes() );
sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, myLastCreatedElems );
-
+ if ( theMakeWalls )
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes,
+ theElems, theNbSteps, myLastCreatedElems );
}
//=======================================================================
//function : CreateNode
-//purpose :
+//purpose :
//=======================================================================
const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
const double y,
gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
if(P1.Distance(P2)<tolnode)
return aN;
- }
+ }
}
// create new node and return it
//purpose :
//=======================================================================
-void SMESH_MeshEditor::ExtrusionSweep
- (map<int,const SMDS_MeshElement*> & theElems,
- const gp_Vec& theStep,
- const int theNbSteps,
- TElemOfElemListMap& newElemsMap,
- const int theFlags,
- const double theTolerance)
+void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
+ const gp_Vec& theStep,
+ const int theNbSteps,
+ TElemOfElemListMap& newElemsMap,
+ const int theFlags,
+ const double theTolerance)
{
ExtrusParam aParams;
aParams.myDir = gp_Dir(theStep);
//purpose :
//=======================================================================
-void SMESH_MeshEditor::ExtrusionSweep
- (map<int,const SMDS_MeshElement*> & theElems,
- ExtrusParam& theParams,
- TElemOfElemListMap& newElemsMap,
- const int theFlags,
- const double theTolerance)
+void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
+ ExtrusParam& theParams,
+ TElemOfElemListMap& newElemsMap,
+ const int theFlags,
+ const double theTolerance)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
//TElemOfVecOfMapNodesMap mapElemNewNodes;
// loop on theElems
- map<int, const SMDS_MeshElement* >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
// check element type
- const SMDS_MeshElement* elem = (*itElem).second;
- if ( !elem )
+ const SMDS_MeshElement* elem = *itElem;
+ if ( !elem || elem->GetType() == SMDSAbs_Volume )
continue;
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
//purpose :
//=======================================================================
SMESH_MeshEditor::Extrusion_Error
- SMESH_MeshEditor::ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
- SMESH_subMesh* theTrack,
+ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements,
+ SMESH_subMesh* theTrack,
const SMDS_MeshNode* theN1,
- const bool theHasAngles,
- std::list<double>& theAngles,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint)
+ const bool theHasAngles,
+ list<double>& theAngles,
+ const bool theHasRefPoint,
+ const gp_Pnt& theRefPoint)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
double aT1, aT2, aT, aAngle, aX, aY, aZ;
std::list<double> aPrms;
std::list<double>::iterator aItD;
- std::map<int, const SMDS_MeshElement* >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
gp_Pnt aP3D, aV0;
itElem = theElements.begin();
for ( ; itElem != theElements.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) {
// check element type
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
aTypeE = elem->GetType();
if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) )
continue;
//purpose :
//=======================================================================
-void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
- const gp_Trsf& theTrsf,
- const bool theCopy)
+void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
+ const gp_Trsf& theTrsf,
+ const bool theCopy)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
// elements sharing moved nodes; those of them which have all
// nodes mirrored but are not in theElems are to be reversed
- map<int,const SMDS_MeshElement*> inverseElemSet;
+ TIDSortedElemSet inverseElemSet;
// loop on theElems
- map<int, const SMDS_MeshElement* >::iterator itElem;
+ TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
if ( !elem )
continue;
if ( !theCopy && needReverse ) {
SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
while ( invElemIt->more() ) {
- const SMDS_MeshElement* iel = invElemIt->next();
- inverseElemSet.insert( make_pair(iel->GetID(),iel) );
+ const SMDS_MeshElement* iel = invElemIt->next();
+ inverseElemSet.insert( iel );
}
}
}
return;
if ( !inverseElemSet.empty()) {
- map<int,const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
+ TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
theElems.insert( *invElemIt );
}
};
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
- const SMDS_MeshElement* elem = (*itElem).second;
+ const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() == SMDSAbs_Node )
continue;
}
// find transformed nodes
- const SMDS_MeshNode* nodes[8];
+ vector<const SMDS_MeshNode*> nodes(nbNodes);
int iNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
continue; // not all nodes transformed
if ( theCopy ) {
- // add a new element
- switch ( elemType ) {
- case SMDSAbs_Edge:
- if ( nbNodes == 2 )
- myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ));
- else
- myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
- break;
- case SMDSAbs_Face:
- if ( nbNodes == 3 )
- myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
- else if(nbNodes==4)
- myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]));
- else if(nbNodes==6)
- myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
- nodes[4], nodes[5]));
- else // nbNodes==8
- myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
- nodes[4], nodes[5], nodes[6], nodes[7]));
- break;
- case SMDSAbs_Volume:
- if ( nbNodes == 4 )
- myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] ));
- else if ( nbNodes == 8 )
- myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]));
- else if ( nbNodes == 6 )
- myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ], nodes[ 5 ]));
- else if ( nbNodes == 5 )
- myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
- nodes[ 4 ]));
- else if(nbNodes==10)
- myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]));
- else if(nbNodes==13)
- myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12]));
- else if(nbNodes==15)
- myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]));
- else // nbNodes==20
- myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
- nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
- nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
- nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]));
- break;
- default:;
- }
+ if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() ))
+ myLastCreatedElems.Append( copy );
}
else
{
// reverse element as it was reversed by transformation
if ( nbNodes > 2 )
- aMesh->ChangeElementNodes( elem, nodes, nbNodes );
+ aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
}
}
}
//=======================================================================
//function : FindCoincidentNodes
//purpose : Return list of group of nodes close to each other within theTolerance
-// Search among theNodes or in the whole mesh if theNodes is empty.
+// Search among theNodes or in the whole mesh if theNodes is empty using
+// an Octree algorithm
//=======================================================================
void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes,
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- double tol2 = theTolerance * theTolerance;
-
- list<const SMDS_MeshNode*> nodes;
+ set<const SMDS_MeshNode*> nodes;
if ( theNodes.empty() )
{ // get all nodes in the mesh
SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator();
while ( nIt->more() )
- nodes.push_back( nIt->next() );
+ nodes.insert( nodes.end(),nIt->next());
}
else
+ nodes=theNodes;
+ SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance);
+
+}
+
+//=======================================================================
+/*!
+ * \brief Implementation of search for the node closest to point
+ */
+//=======================================================================
+
+struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
+{
+ /*!
+ * \brief Constructor
+ */
+ SMESH_NodeSearcherImpl( const SMESHDS_Mesh* theMesh )
{
- nodes.insert( nodes.end(), theNodes.begin(), theNodes.end() );
+ set<const SMDS_MeshNode*> nodes;
+ if ( theMesh ) {
+ SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator();
+ while ( nIt->more() )
+ nodes.insert( nodes.end(), nIt->next() );
+ }
+ myOctreeNode = new SMESH_OctreeNode(nodes) ;
}
-
- list<const SMDS_MeshNode*>::iterator it2, it1 = nodes.begin();
- for ( ; it1 != nodes.end(); it1++ )
+ /*!
+ * \brief Do it's job
+ */
+ const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
{
- const SMDS_MeshNode* n1 = *it1;
- gp_Pnt p1( n1->X(), n1->Y(), n1->Z() );
-
- list<const SMDS_MeshNode*> * groupPtr = 0;
- it2 = it1;
- for ( it2++; it2 != nodes.end(); it2++ )
+ SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
+ list<const SMDS_MeshNode*> nodes;
+ const double precision = 1e-6;
+ myOctreeNode->NodesAround( &tgtNode, &nodes, precision );
+
+ double minSqDist = DBL_MAX;
+ Bnd_B3d box;
+ if ( nodes.empty() ) // get all nodes of OctreeNode's closest to thePnt
{
- const SMDS_MeshNode* n2 = *it2;
- gp_Pnt p2( n2->X(), n2->Y(), n2->Z() );
- if ( p1.SquareDistance( p2 ) <= tol2 )
+ // sort leafs by their distance from thePnt
+ typedef map< double, SMESH_OctreeNode* > TDistTreeMap;
+ TDistTreeMap treeMap;
+ list< SMESH_OctreeNode* > treeList;
+ list< SMESH_OctreeNode* >::iterator trIt;
+ treeList.push_back( myOctreeNode );
+ for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt)
{
- if ( !groupPtr ) {
- theGroupsOfNodes.push_back( list<const SMDS_MeshNode*>() );
- groupPtr = & theGroupsOfNodes.back();
- groupPtr->push_back( n1 );
+ SMESH_OctreeNode* tree = *trIt;
+ if ( !tree->isLeaf() ) { // put children to the queue
+ SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator();
+ while ( cIt->more() )
+ treeList.push_back( cIt->next() );
}
- if(groupPtr->front()>n2)
- groupPtr->push_front( n2 );
- else
- groupPtr->push_back( n2 );
- it2 = nodes.erase( it2 );
- it2--;
+ else if ( tree->NbNodes() ) { // put tree to treeMap
+ tree->getBox( box );
+ double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() ));
+ pair<TDistTreeMap::iterator,bool> it_in = treeMap.insert( make_pair( sqDist, tree ));
+ if ( !it_in.second ) // not unique distance to box center
+ treeMap.insert( it_in.first, make_pair( sqDist - 1e-13*treeMap.size(), tree ));
+ }
+ }
+ // find distance after which there is no sense to check tree's
+ double sqLimit = DBL_MAX;
+ TDistTreeMap::iterator sqDist_tree = treeMap.begin();
+ if ( treeMap.size() > 5 ) {
+ SMESH_OctreeNode* closestTree = sqDist_tree->second;
+ closestTree->getBox( box );
+ double limit = sqrt( sqDist_tree->first ) + sqrt ( box.SquareExtent() );
+ sqLimit = limit * limit;
+ }
+ // get all nodes from trees
+ for ( ; sqDist_tree != treeMap.end(); ++sqDist_tree) {
+ if ( sqDist_tree->first > sqLimit )
+ break;
+ SMESH_OctreeNode* tree = sqDist_tree->second;
+ tree->NodesAround( tree->GetNodeIterator()->next(), &nodes );
}
}
+ // find closest among nodes
+ minSqDist = DBL_MAX;
+ const SMDS_MeshNode* closestNode = 0;
+ list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
+ for ( ; nIt != nodes.end(); ++nIt ) {
+ double sqDist = thePnt.SquareDistance( TNodeXYZ( *nIt ) );
+ if ( minSqDist > sqDist ) {
+ closestNode = *nIt;
+ minSqDist = sqDist;
+ }
+ }
+ return closestNode;
}
+ /*!
+ * \brief Destructor
+ */
+ ~SMESH_NodeSearcherImpl() { delete myOctreeNode; }
+private:
+ SMESH_OctreeNode* myOctreeNode;
+};
+
+//=======================================================================
+/*!
+ * \brief Return SMESH_NodeSearcher
+ */
+//=======================================================================
+
+SMESH_NodeSearcher* SMESH_MeshEditor::GetNodeSearcher()
+{
+ return new SMESH_NodeSearcherImpl( GetMeshDS() );
}
//=======================================================================
else
isOk = false;
break;
- case 8: {
+ case 8: {
if(elem->IsQuadratic()) { // Quadratic quadrangle
// 1 5 2
// +---+---+
}
-// =================================================
+// ========================================================
// class : SortableElement
-// purpose : auxilary
-// =================================================
+// purpose : allow sorting elements basing on their nodes
+// ========================================================
class SortableElement : public set <const SMDS_MeshElement*>
{
public:
SortableElement( const SMDS_MeshElement* theElem )
{
- myID = theElem->GetID();
+ myElem = theElem;
SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
while ( nodeIt->more() )
this->insert( nodeIt->next() );
}
- const long GetID() const
- { return myID; }
+ const SMDS_MeshElement* Get() const
+ { return myElem; }
- void SetID(const long anID) const
- { myID = anID; }
+ void Set(const SMDS_MeshElement* e) const
+ { myElem = e; }
private:
- mutable long myID;
+ mutable const SMDS_MeshElement* myElem;
};
+//=======================================================================
+//function : FindEqualElements
+//purpose : Return list of group of elements built on the same nodes.
+// Search among theElements or in the whole mesh if theElements is empty
+//=======================================================================
+void SMESH_MeshEditor::FindEqualElements(set<const SMDS_MeshElement*> & theElements,
+ TListOfListOfElementsID & theGroupsOfElementsID)
+{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
+ typedef set<const SMDS_MeshElement*> TElemsSet;
+ typedef map< SortableElement, int > TMapOfNodeSet;
+ typedef list<int> TGroupOfElems;
+
+ TElemsSet elems;
+ if ( theElements.empty() )
+ { // get all elements in the mesh
+ SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator();
+ while ( eIt->more() )
+ elems.insert( elems.end(), eIt->next());
+ }
+ else
+ elems = theElements;
+
+ vector< TGroupOfElems > arrayOfGroups;
+ TGroupOfElems groupOfElems;
+ TMapOfNodeSet mapOfNodeSet;
+
+ TElemsSet::iterator elemIt = elems.begin();
+ for ( int i = 0, j=0; elemIt != elems.end(); ++elemIt, ++j ) {
+ const SMDS_MeshElement* curElem = *elemIt;
+ SortableElement SE(curElem);
+ int ind = -1;
+ // check uniqueness
+ pair< TMapOfNodeSet::iterator, bool> pp = mapOfNodeSet.insert(make_pair(SE, i));
+ if( !(pp.second) ) {
+ TMapOfNodeSet::iterator& itSE = pp.first;
+ ind = (*itSE).second;
+ arrayOfGroups[ind].push_back(curElem->GetID());
+ }
+ else {
+ groupOfElems.clear();
+ groupOfElems.push_back(curElem->GetID());
+ arrayOfGroups.push_back(groupOfElems);
+ i++;
+ }
+ }
+
+ vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin();
+ for ( ; groupIt != arrayOfGroups.end(); ++groupIt ) {
+ groupOfElems = *groupIt;
+ if ( groupOfElems.size() > 1 ) {
+ groupOfElems.sort();
+ theGroupsOfElementsID.push_back(groupOfElems);
+ }
+ }
+}
//=======================================================================
-//function : MergeEqualElements
-//purpose : Remove all but one of elements built on the same nodes.
+//function : MergeElements
+//purpose : In each given group, substitute all elements by the first one.
//=======================================================================
-void SMESH_MeshEditor::MergeEqualElements()
+void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElementsID)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
+ typedef list<int> TListOfIDs;
+ TListOfIDs rmElemIds; // IDs of elems to remove
+
SMESHDS_Mesh* aMesh = GetMeshDS();
- SMDS_EdgeIteratorPtr eIt = aMesh->edgesIterator();
- SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
- SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator();
-
- list< int > rmElemIds; // IDs of elems to remove
-
- for ( int iDim = 1; iDim <= 3; iDim++ ) {
-
- set< SortableElement > setOfNodeSet;
- while ( 1 ) {
- // get next element
- const SMDS_MeshElement* elem = 0;
- if ( iDim == 1 ) {
- if ( eIt->more() ) elem = eIt->next();
- } else if ( iDim == 2 ) {
- if ( fIt->more() ) elem = fIt->next();
- } else {
- if ( vIt->more() ) elem = vIt->next();
- }
- if ( !elem ) break;
-
- SortableElement SE(elem);
-
- // check uniqueness
- pair< set<SortableElement>::iterator, bool> pp = setOfNodeSet.insert(SE);
- if( !(pp.second) ) {
- set<SortableElement>::iterator itSE = pp.first;
- SortableElement SEold = *itSE;
- if( SEold.GetID() > SE.GetID() ) {
- rmElemIds.push_back( SEold.GetID() );
- (*itSE).SetID(SE.GetID());
- }
- else {
- rmElemIds.push_back( SE.GetID() );
- }
- }
+ TListOfListOfElementsID::iterator groupsIt = theGroupsOfElementsID.begin();
+ while ( groupsIt != theGroupsOfElementsID.end() ) {
+ TListOfIDs& aGroupOfElemID = *groupsIt;
+ aGroupOfElemID.sort();
+ int elemIDToKeep = aGroupOfElemID.front();
+ const SMDS_MeshElement* elemToKeep = aMesh->FindElement(elemIDToKeep);
+ aGroupOfElemID.pop_front();
+ TListOfIDs::iterator idIt = aGroupOfElemID.begin();
+ while ( idIt != aGroupOfElemID.end() ) {
+ int elemIDToRemove = *idIt;
+ const SMDS_MeshElement* elemToRemove = aMesh->FindElement(elemIDToRemove);
+ // add the kept element in groups of removed one (PAL15188)
+ AddToSameGroups( elemToKeep, elemToRemove, aMesh );
+ rmElemIds.push_back( elemIDToRemove );
+ ++idIt;
}
+ ++groupsIt;
}
Remove( rmElemIds, false );
}
+//=======================================================================
+//function : MergeEqualElements
+//purpose : Remove all but one of elements built on the same nodes.
+//=======================================================================
+
+void SMESH_MeshEditor::MergeEqualElements()
+{
+ set<const SMDS_MeshElement*> aMeshElements; /* empty input -
+ to merge equal elements in the whole mesh */
+ TListOfListOfElementsID aGroupsOfElementsID;
+ FindEqualElements(aMeshElements, aGroupsOfElementsID);
+ MergeElements(aGroupsOfElementsID);
+}
+
//=======================================================================
//function : FindFaceInSet
//purpose : Return a face having linked nodes n1 and n2 and which is
//=======================================================================
const SMDS_MeshElement*
- SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const map<int,const SMDS_MeshElement*>& elemSet,
- const map<int,const SMDS_MeshElement*>& avoidSet)
+ SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const TIDSortedElemSet& elemSet,
+ const TIDSortedElemSet& avoidSet)
{
- SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
while ( invElemIt->more() ) { // loop on inverse elements of n1
const SMDS_MeshElement* elem = invElemIt->next();
- if (elem->GetType() != SMDSAbs_Face ||
- avoidSet.find( elem->GetID() ) != avoidSet.end() )
+ if (avoidSet.find( elem ) != avoidSet.end() )
continue;
- if ( !elemSet.empty() && elemSet.find( elem->GetID() ) == elemSet.end())
+ if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
continue;
// get face nodes and find index of n1
int i1, nbN = elem->NbNodes(), iNode = 0;
const SMDS_MeshNode* n2,
const SMDS_MeshElement* elem)
{
- map<int,const SMDS_MeshElement*> elemSet, avoidSet;
+ TIDSortedElemSet elemSet, avoidSet;
if ( elem )
- avoidSet.insert ( make_pair(elem->GetID(),elem) );
+ avoidSet.insert ( elem );
return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
}
list< const SMDS_MeshElement* > curElemList;
list< const SMDS_MeshNode* > nStartList;
- SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator();
+ SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
while ( invElemIt->more() ) {
const SMDS_MeshElement* e = invElemIt->next();
if ( e == curElem || foundElems.insert( e ).second ) {
}
}
}
-
+
// create new elements
SMESHDS_Mesh *aMesh = GetMeshDS();
int aShapeId = FindShape( theFace );
-
+
i1 = 0; i2 = 1;
for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
SMDS_MeshElement* newElem = 0;
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
}
-
+
// change nodes of theFace
const SMDS_MeshNode* newNodes[ 4 ];
newNodes[ 0 ] = linkNodes[ i1 ];
il1 = il1 - nbshift;
// now have to insert nodes between n0 and n1 or n1 and n2 (see below)
// n0 n1 n2 n0 n1 n2
- // +-----+-----+ +-----+-----+
+ // +-----+-----+ +-----+-----+
// \ / | |
// \ / | |
// n5+ +n3 n7+ +n3
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
- SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator(SMDSAbs_Volume);
while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
const SMDS_MeshElement* elem = invElemIt->next();
- if (elem->GetType() != SMDSAbs_Volume)
- continue;
// check, if current volume has link theBetweenNode1 - theBetweenNode2
SMDS_VolumeTool aVolume (elem);
}
//=======================================================================
-//function : ConvertElemToQuadratic
-//purpose :
+/*!
+ * \brief Convert elements contained in a submesh to quadratic
+ * \retval int - nb of checked elements
+ */
//=======================================================================
-void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
- SMESH_MesherHelper* theHelper,
- const bool theForce3d)
+
+int SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm,
+ SMESH_MesherHelper& theHelper,
+ const bool theForce3d)
{
- if( !theSm ) return;
- SMESHDS_Mesh* meshDS = GetMeshDS();
+ int nbElem = 0;
+ if( !theSm ) return nbElem;
SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
while(ElemItr->more())
{
+ nbElem++;
const SMDS_MeshElement* elem = ElemItr->next();
- if( !elem ) continue;
+ if( !elem || elem->IsQuadratic() ) continue;
int id = elem->GetID();
int nbNodes = elem->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
-
+
for(int i = 0; i < nbNodes; i++)
{
aNds[i] = elem->GetNode(i);
}
-
SMDSAbs_ElementType aType = elem->GetType();
+
+ theSm->RemoveElement(elem);
+ GetMeshDS()->SMDS_Mesh::RemoveFreeElement(elem);
+
const SMDS_MeshElement* NewElem = 0;
switch( aType )
{
case SMDSAbs_Edge :
{
- meshDS->RemoveFreeElement(elem, theSm);
- NewElem = theHelper->AddQuadraticEdge(aNds[0], aNds[1], id, theForce3d);
+ NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d);
break;
}
case SMDSAbs_Face :
{
- if(elem->IsQuadratic()) continue;
-
- meshDS->RemoveFreeElement(elem, theSm);
switch(nbNodes)
{
case 3:
- NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+ NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
break;
case 4:
- NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+ NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
break;
default:
continue;
}
- break;
+ break;
}
case SMDSAbs_Volume :
{
- if( elem->IsQuadratic() ) continue;
-
- meshDS->RemoveFreeElement(elem, theSm);
switch(nbNodes)
{
case 4:
- NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
+ NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
break;
case 6:
- NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
+ NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
break;
case 8:
- NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], aNds[6], aNds[7], id, true);
break;
default:
continue;
}
- break;
+ break;
}
default :
continue;
}
if( NewElem )
{
- AddToSameGroups( NewElem, elem, meshDS);
+ AddToSameGroups( NewElem, elem, GetMeshDS());
theSm->AddElement( NewElem );
}
+ if ( NewElem != elem )
+ RemoveElemFromGroups (elem, GetMeshDS());
}
+ return nbElem;
}
//=======================================================================
{
SMESHDS_Mesh* meshDS = GetMeshDS();
- SMESH_MesherHelper* aHelper = new SMESH_MesherHelper(*myMesh);
- aHelper->SetKeyIsQuadratic( true );
- const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
+ SMESH_MesherHelper aHelper(*myMesh);
+ aHelper.SetIsQuadratic( true );
- if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
+ int nbCheckedElems = 0;
+ if ( myMesh->HasShapeToMesh() )
{
- SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-
- const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
+ if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
{
- SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
- aHelper->SetSubShape( (*itsub).second->GetSubShape() );
- ConvertElemToQuadratic(sm, aHelper, theForce3d);
+ SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false);
+ while ( smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
+ aHelper.SetSubShape( sm->GetSubShape() );
+ nbCheckedElems += ConvertElemToQuadratic(smDS, aHelper, theForce3d);
+ }
+ }
}
- aHelper->SetSubShape( aSubMesh->GetSubShape() );
- ConvertElemToQuadratic(aSubMesh->GetSubMeshDS(), aHelper, theForce3d);
}
- else
+ int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes();
+ if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
{
SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator();
while(aEdgeItr->more())
{
const SMDS_MeshEdge* edge = aEdgeItr->next();
- if(edge)
+ if(edge && !edge->IsQuadratic())
{
int id = edge->GetID();
const SMDS_MeshNode* n1 = edge->GetNode(0);
const SMDS_MeshNode* n2 = edge->GetNode(1);
- RemoveElemFromGroups (edge, meshDS);
meshDS->SMDS_Mesh::RemoveFreeElement(edge);
- const SMDS_QuadraticEdge* NewEdge = aHelper->AddQuadraticEdge(n1, n2, id, theForce3d);
- AddToSameGroups(NewEdge, edge, meshDS);
+ const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
+ if ( NewEdge )
+ AddToSameGroups(NewEdge, edge, meshDS);
+ if ( NewEdge != edge )
+ RemoveElemFromGroups (edge, meshDS);
}
}
SMDS_FaceIteratorPtr aFaceItr = meshDS->facesIterator();
{
const SMDS_MeshFace* face = aFaceItr->next();
if(!face || face->IsQuadratic() ) continue;
-
+
int id = face->GetID();
int nbNodes = face->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
aNds[i] = face->GetNode(i);
}
- RemoveElemFromGroups (face, meshDS);
meshDS->SMDS_Mesh::RemoveFreeElement(face);
SMDS_MeshFace * NewFace = 0;
switch(nbNodes)
{
case 3:
- NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+ NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
break;
case 4:
- NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+ NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
break;
default:
continue;
}
- AddToSameGroups(NewFace, face, meshDS);
+ if ( NewFace )
+ AddToSameGroups(NewFace, face, meshDS);
+ if ( NewFace != face )
+ RemoveElemFromGroups (face, meshDS);
}
SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
while(aVolumeItr->more())
{
const SMDS_MeshVolume* volume = aVolumeItr->next();
if(!volume || volume->IsQuadratic() ) continue;
-
+
int id = volume->GetID();
int nbNodes = volume->NbNodes();
vector<const SMDS_MeshNode *> aNds (nbNodes);
aNds[i] = volume->GetNode(i);
}
- RemoveElemFromGroups (volume, meshDS);
meshDS->SMDS_Mesh::RemoveFreeElement(volume);
SMDS_MeshVolume * NewVolume = 0;
switch(nbNodes)
{
case 4:
- NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
- aNds[3], id, true );
+ NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
+ aNds[3], id, true );
break;
case 6:
- NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
- aNds[3], aNds[4], aNds[5], id, true);
+ NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
+ aNds[3], aNds[4], aNds[5], id, true);
break;
case 8:
- NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+ NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+ aNds[4], aNds[5], aNds[6], aNds[7], id, true);
break;
default:
continue;
}
- AddToSameGroups(NewVolume, volume, meshDS);
+ if ( NewVolume )
+ AddToSameGroups(NewVolume, volume, meshDS);
+ if ( NewVolume != volume )
+ RemoveElemFromGroups (volume, meshDS);
}
}
- delete aHelper;
}
//=======================================================================
-//function : RemoveQuadElem
-//purpose :
+/*!
+ * \brief Convert quadratic elements to linear ones and remove quadratic nodes
+ * \retval int - nb of checked elements
+ */
//=======================================================================
-void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *theSm,
- SMDS_ElemIteratorPtr theItr,
- RemoveQuadNodeMap& theRemoveNodeMap)
+
+int SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm,
+ SMDS_ElemIteratorPtr theItr,
+ const int theShapeID)
{
+ int nbElem = 0;
SMESHDS_Mesh* meshDS = GetMeshDS();
while( theItr->more() )
{
const SMDS_MeshElement* elem = theItr->next();
- if( elem )
+ nbElem++;
+ if( elem && elem->IsQuadratic())
{
- if( !elem->IsQuadratic() )
- continue;
-
int id = elem->GetID();
-
- int nbNodes = elem->NbNodes(), idx = 0;
- vector<const SMDS_MeshNode *> aNds;
+ int nbNodes = elem->NbNodes();
+ vector<const SMDS_MeshNode *> aNds, mediumNodes;
+ aNds.reserve( nbNodes );
+ mediumNodes.reserve( nbNodes );
for(int i = 0; i < nbNodes; i++)
{
const SMDS_MeshNode* n = elem->GetNode(i);
if( elem->IsMediumNode( n ) )
- {
- ItRemoveQuadNodeMap itRNM = theRemoveNodeMap.find( n );
- if( itRNM == theRemoveNodeMap.end() )
- {
- theRemoveNodeMap.insert(RemoveQuadNodeMap::value_type( n,theSm ));
- }
- }
- else
+ mediumNodes.push_back( n );
+ else
aNds.push_back( n );
}
+ if( aNds.empty() ) continue;
+ SMDSAbs_ElementType aType = elem->GetType();
- idx = aNds.size();
- if( !idx ) continue;
- SMDSAbs_ElementType aType = elem->GetType();
-
- //remove old quadratic elements
- meshDS->RemoveFreeElement( elem, theSm );
+ //remove old quadratic element
+ meshDS->SMDS_Mesh::RemoveFreeElement( elem );
+ if ( theSm )
+ theSm->RemoveElement( elem );
- SMDS_MeshElement * NewElem = 0;
- switch(aType)
- {
- case SMDSAbs_Edge:
- NewElem = meshDS->AddEdgeWithID( aNds[0], aNds[1] ,id );
- break;
- case SMDSAbs_Face:
- if( idx==3 ) NewElem = meshDS->AddFaceWithID( aNds[0],
- aNds[1], aNds[2], id );
- if( idx==4 ) NewElem = meshDS->AddFaceWithID( aNds[0],
- aNds[1], aNds[2], aNds[3],id );
- break;
- case SMDSAbs_Volume:
- if( idx==4 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
- aNds[1], aNds[2], aNds[3], id );
- if( idx==6 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
- aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], id );
- if( idx==8 ) NewElem = meshDS->AddVolumeWithID(aNds[0],
- aNds[1], aNds[2], aNds[3],
- aNds[4], aNds[5], aNds[6],
- aNds[7] ,id );
- break;
- default:
- break;
- }
-
- AddToSameGroups(NewElem, elem, meshDS);
- if( theSm )
+ SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id );
+ if ( NewElem )
+ AddToSameGroups(NewElem, elem, meshDS);
+ if ( NewElem != elem )
+ RemoveElemFromGroups (elem, meshDS);
+ if( theSm && NewElem )
theSm->AddElement( NewElem );
+
+ // remove medium nodes
+ vector<const SMDS_MeshNode*>::iterator nIt = mediumNodes.begin();
+ for ( ; nIt != mediumNodes.end(); ++nIt ) {
+ const SMDS_MeshNode* n = *nIt;
+ if ( n->NbInverseNodes() == 0 ) {
+ if ( n->GetPosition()->GetShapeId() != theShapeID )
+ meshDS->RemoveFreeNode( n, meshDS->MeshElements
+ ( n->GetPosition()->GetShapeId() ));
+ else
+ meshDS->RemoveFreeNode( n, theSm );
+ }
+ }
}
}
+ return nbElem;
}
+
//=======================================================================
//function : ConvertFromQuadratic
//purpose :
//=======================================================================
bool SMESH_MeshEditor::ConvertFromQuadratic()
{
- SMESHDS_Mesh* meshDS = GetMeshDS();
- RemoveQuadNodeMap aRemoveNodeMap;
-
- const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
-
- if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
+ int nbCheckedElems = 0;
+ if ( myMesh->HasShapeToMesh() )
{
- SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-
- const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
+ if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
{
- SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
- if( sm )
- RemoveQuadElem( sm, sm->GetElements(), aRemoveNodeMap );
+ SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false);
+ while ( smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() )
+ nbCheckedElems += RemoveQuadElem( smDS, smDS->GetElements(), sm->GetId() );
+ }
}
- SMESHDS_SubMesh *Sm = aSubMesh->GetSubMeshDS();
- if( Sm )
- RemoveQuadElem( Sm, Sm->GetElements(), aRemoveNodeMap );
}
- else
+
+ int totalNbElems =
+ GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
+ if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
{
SMESHDS_SubMesh *aSM = 0;
- RemoveQuadElem( aSM, meshDS->elementsIterator(), aRemoveNodeMap );
- }
-
- //remove all quadratic nodes
- ItRemoveQuadNodeMap itRNM = aRemoveNodeMap.begin();
- for ( ; itRNM != aRemoveNodeMap.end(); itRNM++ )
- {
- meshDS->RemoveFreeNode( (*itRNM).first, (*itRNM).second );
+ RemoveQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
}
return true;
//=======================================================================
SMESH_MeshEditor::Sew_Error
- SMESH_MeshEditor::SewSideElements (map<int,const SMDS_MeshElement*>& theSide1,
- map<int,const SMDS_MeshElement*>& theSide2,
- const SMDS_MeshNode* theFirstNode1,
- const SMDS_MeshNode* theFirstNode2,
- const SMDS_MeshNode* theSecondNode1,
- const SMDS_MeshNode* theSecondNode2)
+ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1,
+ TIDSortedElemSet& theSide2,
+ const SMDS_MeshNode* theFirstNode1,
+ const SMDS_MeshNode* theFirstNode2,
+ const SMDS_MeshNode* theSecondNode1,
+ const SMDS_MeshNode* theSecondNode2)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
set<const SMDS_MeshElement*> * faceSetPtr[] = { &faceSet1, &faceSet2 };
set<const SMDS_MeshElement*> * volSetPtr[] = { &volSet1, &volSet2 };
set<const SMDS_MeshNode*> * nodeSetPtr[] = { &nodeSet1, &nodeSet2 };
- map<int,const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
+ TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 };
int iSide, iFace, iNode;
for ( iSide = 0; iSide < 2; iSide++ ) {
set<const SMDS_MeshNode*> * nodeSet = nodeSetPtr[ iSide ];
- map<int,const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
+ TIDSortedElemSet * elemSet = elemSetPtr[ iSide ];
set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
set<const SMDS_MeshElement*> * volSet = volSetPtr [ iSide ];
set<const SMDS_MeshElement*>::iterator vIt;
- map<int,const SMDS_MeshElement*>::iterator eIt;
+ TIDSortedElemSet::iterator eIt;
set<const SMDS_MeshNode*>::iterator nIt;
// check that given nodes belong to given elements
const SMDS_MeshNode* n2 = ( iSide == 0 ) ? theSecondNode1 : theSecondNode2;
int firstIndex = -1, secondIndex = -1;
for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
- const SMDS_MeshElement* elem = (*eIt).second;
+ const SMDS_MeshElement* elem = *eIt;
if ( firstIndex < 0 ) firstIndex = elem->GetNodeIndex( n1 );
if ( secondIndex < 0 ) secondIndex = elem->GetNodeIndex( n2 );
if ( firstIndex > -1 && secondIndex > -1 ) break;
// loop on the given element of a side
for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
//const SMDS_MeshElement* elem = *eIt;
- const SMDS_MeshElement* elem = (*eIt).second;
+ const SMDS_MeshElement* elem = *eIt;
if ( elem->GetType() == SMDSAbs_Face ) {
faceSet->insert( elem );
set <const SMDS_MeshNode*> faceNodeSet;
// ------------------------------------------------------------------------------
for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
- SMDS_ElemIteratorPtr fIt = (*nIt)->facesIterator();
+ SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
while ( fIt->more() ) { // loop on faces sharing a node
const SMDS_MeshElement* f = fIt->next();
if ( faceSet->find( f ) == faceSet->end() ) {
const SMDS_MeshElement* e = invElemIt->next();
if ( faceSet->find( e ) != faceSet->end() )
nbSharedNodes++;
- if ( elemSet->find( e->GetID() ) != elemSet->end() )
+ if ( elemSet->find( e ) != elemSet->end() )
nbSharedNodes++;
}
}
// choose a face most close to the bary center of the opposite side
gp_XYZ aBC( 0., 0., 0. );
set <const SMDS_MeshNode*> addedNodes;
- map<int,const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
+ TIDSortedElemSet * elemSet2 = elemSetPtr[ 1 - iSide ];
eIt = elemSet2->begin();
for ( eIt = elemSet2->begin(); eIt != elemSet2->end(); eIt++ ) {
- SMDS_ElemIteratorPtr nodeIt = (*eIt).second->nodesIterator();
+ SMDS_ElemIteratorPtr nodeIt = (*eIt)->nodesIterator();
while ( nodeIt->more() ) { // loop on free face nodes
const SMDS_MeshNode* n =
static_cast<const SMDS_MeshNode*>( nodeIt->next() );
// // ----------------------------------------------------------
// if ( nodeSetSize != nodeSet->size() ) {
// for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
-// SMDS_ElemIteratorPtr fIt = (*nIt)->facesIterator();
+// SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
// while ( fIt->more() ) { // loop on faces sharing a node
// const SMDS_MeshElement* f = fIt->next();
// if ( faceSet->find( f ) == faceSet->end() ) {
set< const SMDS_MeshElement* > fMap;
for ( int i = 0; i < 2; i++ ) { // loop on 2 nodes of a link
const SMDS_MeshNode* n = i ? n1 : n2; // a node of a link
- SMDS_ElemIteratorPtr fIt = n->facesIterator();
+ SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
while ( fIt->more() ) { // loop on faces sharing a node
const SMDS_MeshElement* f = fIt->next();
if (faceSet->find( f ) != faceSet->end() && // f is in face set
return aResult;
}
-/*!
- * \brief A sorted pair of nodes
- */
-struct TLink: public NLink
-{
- TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
- { if ( n1 < n2 ) std::swap( first, second ); }
- TLink(const NLink& link ):NLink( link )
- { if ( first < second ) std::swap( first, second ); }
-};
-
//================================================================================
/*!
- * \brief Find corresponding nodes in two sets of faces
+ * \brief Find corresponding nodes in two sets of faces
* \param theSide1 - first face set
* \param theSide2 - second first face
* \param theFirstNode1 - a boundary node of set 1
// during a loop of the first node, we find all faces around n1,
// during a loop of the second node, we find one face sharing both n1 and n2
const SMDS_MeshNode* n = iNode ? n1 : n2; // a node of a link
- SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
while ( fIt->more() ) { // loop on faces sharing a node
const SMDS_MeshElement* f = fIt->next();
- if (f->GetType() == SMDSAbs_Face &&
- faceSet->find( f ) != faceSet->end() && // f is in face set
+ if (faceSet->find( f ) != faceSet->end() && // f is in face set
! facesOfNode1.insert( f ).second ) // f encounters twice
{
if ( face[ iSide ] ) {
#include "SMESH_Controls.hxx"
#include "SMESH_SequenceOfNode.hxx"
#include "SMESH_SequenceOfElemPtr.hxx"
-#include "gp_Dir.hxx"
#include "TColStd_HSequenceOfReal.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMDS_MeshElement.hxx"
+#include <gp_Dir.hxx>
+
#include <list>
#include <map>
-typedef map<const SMDS_MeshElement*,
- list<const SMDS_MeshElement*> > TElemOfElemListMap;
-typedef map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
-
-typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*> RemoveQuadNodeMap;
-typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*>::iterator ItRemoveQuadNodeMap;
+typedef std::map<const SMDS_MeshElement*,
+ std::list<const SMDS_MeshElement*> > TElemOfElemListMap;
+typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
class SMDS_MeshFace;
class SMDS_MeshNode;
class gp_Vec;
class gp_Pnt;
+// ============================================================
+/*!
+ * \brief Set of elements sorted by ID, to be used to assure
+ * predictability of edition
+ */
+// ============================================================
+
+template < class TMeshElem = SMDS_MeshElement>
+struct TIDCompare {
+ bool operator () (const TMeshElem* e1, const TMeshElem* e2) const
+ { return e1->GetID() < e2->GetID(); }
+};
+typedef std::set< const SMDS_MeshElement*, TIDCompare< SMDS_MeshElement> > TIDSortedElemSet;
+
+// ============================================================
+/*!
+ * \brief Searcher for the node closest to point
+ */
+// ============================================================
+
+struct SMESH_NodeSearcher
+{
+ virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0;
+};
+
+// ============================================================
+/*!
+ * \brief Editor of a mesh
+ */
+// ============================================================
+
class SMESH_EXPORT SMESH_MeshEditor {
+
public:
- // define a set of elements sorted by ID, to be used to assure
- // predictability of edition
- struct TIDCompare {
- bool operator () (const SMDS_MeshElement* e1, const SMDS_MeshElement* e2)
- { return e1->GetID() < e2->GetID(); }
- };
- typedef set< const SMDS_MeshElement*, TIDCompare > TIDSortedElemSet;
+ SMESH_MeshEditor( SMESH_Mesh* theMesh );
/*!
- * \brief Insert element in a map of elements sorted by ID
- * \param elem - element to insert
- * \param elemMap - the map to fill in
+ * \brief Add element
*/
- static void Insert(const SMDS_MeshElement* elem,
- std::map<int,const SMDS_MeshElement*> & elemMap) {
- elemMap.insert( make_pair( elem->GetID(), elem ));
- }
-
-public:
-
- SMESH_MeshEditor( SMESH_Mesh* theMesh );
+ SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
+ const SMDSAbs_ElementType type,
+ const bool isPoly,
+ const int ID = 0);
+ /*!
+ * \brief Add element
+ */
+ SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
+ const SMDSAbs_ElementType type,
+ const bool isPoly,
+ const int ID = 0);
bool Remove (const std::list< int >& theElemIDs, const bool isNodes);
// Remove a node or an element.
* is still performed; theMaxAngle is mesured in radians.
* \retval bool - Success or not.
*/
- bool TriToQuad (std::map<int,const SMDS_MeshElement*> & theElems,
+ bool TriToQuad (TIDSortedElemSet & theElems,
SMESH::Controls::NumericalFunctorPtr theCriterion,
const double theMaxAngle);
* \param theCriterion - Is used to choose a diagonal for splitting.
* \retval bool - Success or not.
*/
- bool QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
+ bool QuadToTri (TIDSortedElemSet & theElems,
SMESH::Controls::NumericalFunctorPtr theCriterion);
/*!
* \param the13Diag - Is used to choose a diagonal for splitting.
* \retval bool - Success or not.
*/
- bool QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
- const bool the13Diag);
+ bool QuadToTri (TIDSortedElemSet & theElems,
+ const bool the13Diag);
/*!
* \brief Find better diagonal for splitting.
enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
- void Smooth (std::map<int,const SMDS_MeshElement*> & theElements,
- std::set<const SMDS_MeshNode*> & theFixedNodes,
- const SmoothMethod theSmoothMethod,
- const int theNbIterations,
- double theTgtAspectRatio = 1.0,
- const bool the2D = true);
+ void Smooth (TIDSortedElemSet & theElements,
+ std::set<const SMDS_MeshNode*> & theFixedNodes,
+ const SmoothMethod theSmoothMethod,
+ const int theNbIterations,
+ double theTgtAspectRatio = 1.0,
+ const bool the2D = true);
// Smooth theElements using theSmoothMethod during theNbIterations
// or until a worst element has aspect ratio <= theTgtAspectRatio.
// Aspect Ratio varies in range [1.0, inf].
// on geometrical faces
- void RotationSweep (std::map<int,const SMDS_MeshElement*> & theElements,
- const gp_Ax1& theAxis,
- const double theAngle,
- const int theNbSteps,
- const double theToler);
+ void RotationSweep (TIDSortedElemSet & theElements,
+ const gp_Ax1& theAxis,
+ const double theAngle,
+ const int theNbSteps,
+ const double theToler,
+ const bool theMakeWalls=true);
// Generate new elements by rotation of theElements around theAxis
// by theAngle by theNbSteps
* EXTRUSION_FLAG_SEW is set
*/
void ExtrusionSweep
- (map<int,const SMDS_MeshElement*> & theElems,
- const gp_Vec& theStep,
- const int theNbSteps,
- TElemOfElemListMap& newElemsMap,
- const int theFlags = EXTRUSION_FLAG_BOUNDARY,
- const double theTolerance = 1.e-6);
+ (TIDSortedElemSet & theElems,
+ const gp_Vec& theStep,
+ const int theNbSteps,
+ TElemOfElemListMap& newElemsMap,
+ const int theFlags = EXTRUSION_FLAG_BOUNDARY,
+ const double theTolerance = 1.e-6);
/*!
* Generate new elements by extrusion of theElements
* EXTRUSION_FLAG_SEW is set
* param theParams - special structure for manage of extrusion
*/
- void ExtrusionSweep (map<int,const SMDS_MeshElement*> & theElems,
- ExtrusParam& theParams,
- TElemOfElemListMap& newElemsMap,
- const int theFlags,
- const double theTolerance);
+ void ExtrusionSweep (TIDSortedElemSet & theElems,
+ ExtrusParam& theParams,
+ TElemOfElemListMap& newElemsMap,
+ const int theFlags,
+ const double theTolerance);
// Generate new elements by extrusion of theElements
EXTR_CANT_GET_TANGENT
};
- Extrusion_Error ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
- SMESH_subMesh* theTrackPattern,
- const SMDS_MeshNode* theNodeStart,
- const bool theHasAngles,
- std::list<double>& theAngles,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint);
+ Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements,
+ SMESH_subMesh* theTrackPattern,
+ const SMDS_MeshNode* theNodeStart,
+ const bool theHasAngles,
+ std::list<double>& theAngles,
+ const bool theHasRefPoint,
+ const gp_Pnt& theRefPoint);
// Generate new elements by extrusion of theElements along path given by theTrackPattern,
// theHasAngles are the rotation angles, base point can be given by theRefPoint
- void Transform (std::map<int,const SMDS_MeshElement*> & theElements,
- const gp_Trsf& theTrsf,
- const bool theCopy);
+ void Transform (TIDSortedElemSet & theElements,
+ const gp_Trsf& theTrsf,
+ const bool theCopy);
// Move or copy theElements applying theTrsf to their nodes
typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
// Return list of group of nodes close to each other within theTolerance.
// Search among theNodes or in the whole mesh if theNodes is empty.
+ /*!
+ * \brief Return SMESH_NodeSearcher
+ */
+ SMESH_NodeSearcher* GetNodeSearcher();
+
int SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
vector<const SMDS_MeshNode *>& poly_nodes,
vector<int>& quantities) const;
// In each group, the cdr of nodes are substituted by the first one
// in all elements.
+ typedef std::list< std::list< int > > TListOfListOfElementsID;
+
+ void FindEqualElements(std::set<const SMDS_MeshElement*> & theElements,
+ TListOfListOfElementsID & theGroupsOfElementsID);
+ // Return list of group of elements build on the same nodes.
+ // Search among theElements or in the whole mesh if theElements is empty.
+
+ void MergeElements(TListOfListOfElementsID & theGroupsOfElementsID);
+ // In each group remove all but first of elements.
+
void MergeEqualElements();
// Remove all but one of elements built on the same nodes.
// Return nb of successfully merged groups.
// nodes are inserted.
// Return false, if sewing failed.
- Sew_Error SewSideElements (std::map<int,const SMDS_MeshElement*>& theSide1,
- std::map<int,const SMDS_MeshElement*>& theSide2,
- const SMDS_MeshNode* theFirstNode1ToMerge,
- const SMDS_MeshNode* theFirstNode2ToMerge,
- const SMDS_MeshNode* theSecondNode1ToMerge,
- const SMDS_MeshNode* theSecondNode2ToMerge);
+ Sew_Error SewSideElements (TIDSortedElemSet& theSide1,
+ TIDSortedElemSet& theSide2,
+ const SMDS_MeshNode* theFirstNode1ToMerge,
+ const SMDS_MeshNode* theFirstNode2ToMerge,
+ const SMDS_MeshNode* theSecondNode1ToMerge,
+ const SMDS_MeshNode* theSecondNode2ToMerge);
// Sew two sides of a mesh. Nodes belonging to theSide1 are
// merged with nodes of elements of theSide2.
// Number of elements in theSide1 and in theSide2 must be
static void RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
SMESHDS_Mesh * aMesh);
- // remove elemToAdd from the groups
+ // remove elemToAdd from the groups
+
+ /*!
+ * \brief Return nodes linked to the given one in elements of the type
+ */
+ static void GetLinkedNodes( const SMDS_MeshNode* node,
+ TIDSortedElemSet & linkedNodes,
+ SMDSAbs_ElementType type = SMDSAbs_All );
static const SMDS_MeshElement*
- FindFaceInSet(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const std::map<int,const SMDS_MeshElement*>& elemSet,
- const std::map<int,const SMDS_MeshElement*>& avoidSet);
+ FindFaceInSet(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const TIDSortedElemSet& elemSet,
+ const TIDSortedElemSet& avoidSet);
// Return a face having linked nodes n1 and n2 and which is
// - not in avoidSet,
// - in elemSet provided that !elemSet.empty()
SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
- SMESH_SequenceOfElemPtr GetLastCreatedNodes() { return myLastCreatedNodes; }
+ const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
- SMESH_SequenceOfElemPtr GetLastCreatedElems() { return myLastCreatedElems; }
+ const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
private:
- void ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
- SMESH_MesherHelper* theHelper,
- const bool theForce3d);
- //Auxiliary function for "ConvertToQuadratic" is intended to convert
- //elements contained in submesh to quadratic
-
- void RemoveQuadElem( SMESHDS_SubMesh *theSm,
- SMDS_ElemIteratorPtr theItr,
- RemoveQuadNodeMap& theRemoveNodeMap);
- //Auxiliary function for "ConvertFromQuadratic" is intended to convert quadratic
- //element to ordinary and for removing quadratic nodes
+ /*!
+ * \brief Convert elements contained in a submesh to quadratic
+ * \retval int - nb of checked elements
+ */
+ int ConvertElemToQuadratic(SMESHDS_SubMesh * theSm,
+ SMESH_MesherHelper& theHelper,
+ const bool theForce3d);
+
+ /*!
+ * \brief Convert quadratic elements to linear ones and remove quadratic nodes
+ * \retval int - nb of checked elements
+ */
+ int RemoveQuadElem( SMESHDS_SubMesh * theSm,
+ SMDS_ElemIteratorPtr theItr,
+ const int theShapeID);
+ //Auxiliary function for "ConvertFromQuadratic" is intended to
private:
#define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; }
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
+ : myMesh(&theMesh), myShapeID(-1), myCreateQuadratic(false)
+{
+ mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
+}
+
//=======================================================================
//function : CheckShape
//purpose :
if ( aShID == myShapeID )
return;
if ( aShID > 1 )
- SetSubShape( GetMesh()->GetMeshDS()->IndexToShape( aShID ));
+ SetSubShape( GetMeshDS()->IndexToShape( aShID ));
else
SetSubShape( TopoDS_Shape() );
}
// edge and recieve value from this pcurve
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
- SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh* meshDS = GetMeshDS();
int edgeID = Pos->GetShapeId();
TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
double f, l;
param = epos->GetUParameter();
}
else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) {
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
int vertexID = n->GetPosition()->GetShapeId();
const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
param = BRep_Tool::Parameter( V, E );
}
//=======================================================================
-//function : AddQuadraticEdge
-//purpose :
+/*!
+ * Creates a node
+ */
+//=======================================================================
+
+SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID)
+{
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshNode* node = 0;
+ if ( ID )
+ node = meshDS->AddNodeWithID( x, y, z, ID );
+ else
+ node = meshDS->AddNode( x, y, z );
+ if ( mySetElemOnShape && myShapeID > 0 ) {
+ switch ( myShape.ShapeType() ) {
+ case TopAbs_SOLID: meshDS->SetNodeInVolume( node, myShapeID); break;
+ case TopAbs_SHELL: meshDS->SetNodeInVolume( node, myShapeID); break;
+ case TopAbs_FACE: meshDS->SetNodeOnFace( node, myShapeID); break;
+ case TopAbs_EDGE: meshDS->SetNodeOnEdge( node, myShapeID); break;
+ case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID); break;
+ default: ;
+ }
+ }
+ return node;
+}
+
//=======================================================================
-/**
- * Special function for creation quadratic edge
+/*!
+ * Creates quadratic or linear edge
*/
-SMDS_QuadraticEdge* SMESH_MesherHelper::AddQuadraticEdge(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const int id,
- const bool force3d)
+//=======================================================================
+
+SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const int id,
+ const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-
- myCreateQuadratic = true;
+ SMDS_MeshEdge* edge = 0;
+ if (myCreateQuadratic) {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ if(id)
+ edge = meshDS->AddEdgeWithID(n1, n2, n12, id);
+ else
+ edge = meshDS->AddEdge(n1, n2, n12);
+ }
+ else {
+ if(id)
+ edge = meshDS->AddEdgeWithID(n1, n2, id);
+ else
+ edge = meshDS->AddEdge(n1, n2);
+ }
- if(id)
- return (SMDS_QuadraticEdge*)(meshDS->AddEdgeWithID(n1, n2, n12, id));
- else
- return (SMDS_QuadraticEdge*)(meshDS->AddEdge(n1, n2, n12));
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( edge, myShapeID );
+
+ return edge;
}
-//=======================================================================
-//function : AddFace
-//purpose :
//=======================================================================
/*!
- * Special function for creation quadratic triangle
+ * Creates quadratic or linear triangle
*/
+//=======================================================================
+
SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const int id,
const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshFace* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return meshDS->AddFaceWithID(n1, n2, n3, id);
+ elem = meshDS->AddFaceWithID(n1, n2, n3, id);
else
- return meshDS->AddFace(n1, n2, n3);
+ elem = meshDS->AddFace(n1, n2, n3);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+ if(id)
+ elem = meshDS->AddFaceWithID(n1, n2, n3, n12, n23, n31, id);
+ else
+ elem = meshDS->AddFace(n1, n2, n3, n12, n23, n31);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return meshDS->AddFaceWithID(n1, n2, n3, n12, n23, n31, id);
- else
- return meshDS->AddFace(n1, n2, n3, n12, n23, n31);
+ return elem;
}
-
-//=======================================================================
-//function : AddFace
-//purpose :
//=======================================================================
/*!
- * Special function for creation quadratic quadrangle
+ * Creates quadratic or linear quadrangle
*/
+//=======================================================================
+
SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const int id,
const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshFace* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return meshDS->AddFaceWithID(n1, n2, n3, n4, id);
+ elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id);
else
- return meshDS->AddFace(n1, n2, n3, n4);
+ elem = meshDS->AddFace(n1, n2, n3, n4);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+ const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
- const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+ if(id)
+ elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
+ else
+ elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
- else
- return meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+ return elem;
}
-
-//=======================================================================
-//function : AddVolume
-//purpose :
//=======================================================================
/*!
- * Special function for creation quadratic volume
+ * Creates quadratic or linear volume
*/
+//=======================================================================
+
SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const int id,
const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshVolume* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
else
- return meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+ const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
+ const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
+ const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);
- const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
- const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
- const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);
+ const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
+ const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
+ const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);
- const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
- const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
- const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);
+ if(id)
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+ else
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
- n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
- else
- return meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
- n12, n23, n31, n45, n56, n64, n14, n25, n36);
+ return elem;
}
//=======================================================================
/*!
- * Special function for creation quadratic volume
+ * Creates quadratic or linear volume
*/
//=======================================================================
const int id,
const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshVolume* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, id);
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, id);
else
- return meshDS->AddVolume(n1, n2, n3, n4);
+ elem = meshDS->AddVolume(n1, n2, n3, n4);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+ const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
+ const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
- const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
- const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
- const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+ if(id)
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
+ else
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
- else
- return meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
+ return elem;
}
//=======================================================================
/*!
- * Special function for creation quadratic pyramid
+ * Creates quadratic or linear pyramid
*/
//=======================================================================
const int id,
const bool force3d)
{
+ SMDS_MeshVolume* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return GetMeshDS()->AddVolumeWithID(n1, n2, n3, n4, n5, id);
+ elem = GetMeshDS()->AddVolumeWithID(n1, n2, n3, n4, n5, id);
else
- return GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
+ elem = GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+ const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
- const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+ const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
+ const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
+ const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
+ const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
- const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
- const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
- const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
- const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
+ if(id)
+ elem = GetMeshDS()->AddVolumeWithID ( n1, n2, n3, n4, n5,
+ n12, n23, n34, n41,
+ n15, n25, n35, n45,
+ id);
+ else
+ elem = GetMeshDS()->AddVolume( n1, n2, n3, n4, n5,
+ n12, n23, n34, n41,
+ n15, n25, n35, n45);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ GetMeshDS()->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return GetMeshDS()->AddVolumeWithID ( n1, n2, n3, n4, n5,
- n12, n23, n34, n41,
- n15, n25, n35, n45,
- id);
- else
- return GetMeshDS()->AddVolume( n1, n2, n3, n4, n5,
- n12, n23, n34, n41,
- n15, n25, n35, n45);
+ return elem;
}
//=======================================================================
/*!
- * Special function for creation of quadratic hexahedron
+ * Creates quadratic or linear hexahedron
*/
//=======================================================================
const int id,
const bool force3d)
{
- SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ SMDS_MeshVolume* elem = 0;
if(!myCreateQuadratic) {
if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, id);
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, id);
else
- return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
}
+ else {
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+ const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
- const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
- const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
- const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
- const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+ const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
+ const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
+ const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
+ const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);
- const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
- const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
- const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
- const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);
+ const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
+ const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
+ const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
+ const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
- const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
- const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
- const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
- const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
+ if(id)
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
+ n12, n23, n34, n41, n56, n67,
+ n78, n85, n15, n26, n37, n48, id);
+ else
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
+ n12, n23, n34, n41, n56, n67,
+ n78, n85, n15, n26, n37, n48);
+ }
+ if ( mySetElemOnShape && myShapeID > 0 )
+ meshDS->SetMeshElementOnShape( elem, myShapeID );
- if(id)
- return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
- n12, n23, n34, n41, n56, n67,
- n78, n85, n15, n26, n37, n48, id);
- else
- return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
- n12, n23, n34, n41, n56, n67,
- n78, n85, n15, n26, n37, n48);
+ return elem;
}
//=======================================================================
const SMDS_MeshNode* node;
while ( nIt->more() ) {
node = nIt->next();
- if(IsMedium(node))
+ if(IsMedium(node, SMDSAbs_Edge))
continue;
const SMDS_EdgePosition* pos =
dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
// try to load the rest nodes
// get all faces from theFace
- map<int,const SMDS_MeshElement*> allFaces, foundFaces;
+ TIDSortedElemSet allFaces, foundFaces;
eIt = smFace->GetElements();
while ( eIt->more() ) {
const SMDS_MeshElement* e = eIt->next();
if ( e->GetType() == SMDSAbs_Face )
- allFaces.insert( make_pair(e->GetID(),e) );
+ allFaces.insert( e );
}
// Starting from 2 neighbour nodes on theBaseEdge, look for a face
// the nodes belong to, and between the nodes of the found face,
RETURN_BAD_RESULT( "Too many nodes in column "<< col <<": "<< row+1);
}
par_nVec_2->second[ row ] = node;
- foundFaces.insert( make_pair(face->GetID(),face) );
+ foundFaces.insert( face );
n2 = node;
if ( nbFaceNodes==4 ) {
n1 = par_nVec_1->second[ row ];
public:
// ---------- PUBLIC UTILITIES ----------
+ /*!
+ * \brief Returns true if given node is medium
+ * \param n - node to check
+ * \param typeToCheck - type of elements containing the node to ask about node status
+ * \retval bool - check result
+ */
+ static bool IsMedium(const SMDS_MeshNode* node,
+ const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
+
/*!
* \brief Load nodes bound to face into a map of node columns
* \param theParam2ColumnMap - map of node columns to fill
}
public:
- // ---------- PUBLIC METHODS ----------
+ // ---------- PUBLIC INSTANCE METHODS ----------
- /// Empty constructor
- SMESH_MesherHelper(SMESH_Mesh& theMesh)
- { myMesh=(void *)&theMesh; myCreateQuadratic = false; myShapeID=-1;}
+ // constructor
+ SMESH_MesherHelper(SMESH_Mesh& theMesh);
- SMESH_Mesh* GetMesh() const { return (SMESH_Mesh*)myMesh; }
+ SMESH_Mesh* GetMesh() const { return myMesh; }
SMESHDS_Mesh* GetMeshDS() const { return GetMesh()->GetMeshDS(); }
- /// Copy constructor
- //Standard_EXPORT SMESH_MesherHelper (const SMESH_MesherHelper& theOther);
-
- /// Destructor
- //Standard_EXPORT virtual ~SMESH_MesherHelper ();
-
- /**
- * Check submesh for given shape
- * Check if all elements on this shape
- * are quadratic, if yes => set true to myCreateQuadratic
- * (default value is false). Also fill myNLinkNodeMap
- * Returns myCreateQuadratic
+ /*!
+ * Check submesh for given shape: if all elements on this shape are quadratic,
+ * quadratic elements will be created. Also fill myNLinkNodeMap
*/
bool IsQuadraticSubMesh(const TopoDS_Shape& theShape);
-
/*!
- * \brief Returns true if given node is medium
- * \param n - node to check
- * \param typeToCheck - type of elements containing the node to ask about node status
- * \retval bool - check result
+ * \brief Set order of elements to create without calling IsQuadraticSubMesh()
*/
- static bool IsMedium(const SMDS_MeshNode* node,
- const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
-
- /**
- * Auxilary function for filling myNLinkNodeMap
- */
- void AddNLinkNode(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const SMDS_MeshNode* n12);
-
- /**
- * Auxilary function for filling myNLinkNodeMap
+ void SetIsQuadratic(const bool theBuildQuadratic)
+ { myCreateQuadratic = theBuildQuadratic; }
+ /*!
+ * \brief Return myCreateQuadratic flag
*/
- void AddNLinkNodeMap(const NLinkNodeMap& aMap)
- { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+ bool GetIsQuadratic() const { return myCreateQuadratic; }
- /**
- * Returns myNLinkNodeMap
+ /*!
+ * \brief To set created elements on the shape set by IsQuadraticSubMesh()
+ * or the next methods. By defaul elements are set on the shape if
+ * a mesh has no shape to be meshed
*/
- const NLinkNodeMap& GetNLinkNodeMap() { return myNLinkNodeMap; }
+ void SetElementsOnShape(bool toSet) { mySetElemOnShape = toSet; }
/*!
- * \brief Return node UV on face
- * \param F - the face
- * \param n - the node
- * \param inFaceNode - a node of element being created located inside a face
- * \retval gp_XY - resulting UV
- *
- * Auxilary function called form GetMediumNode()
+ * \brief Set shape to make elements on without calling IsQuadraticSubMesh()
*/
- gp_XY GetNodeUV(const TopoDS_Face& F,
- const SMDS_MeshNode* n,
- const SMDS_MeshNode* inFaceNode=0) const;
-
+ void SetSubShape(const int subShapeID);//!==SMESHDS_Mesh::ShapeToIndex(shape)
+ void SetSubShape(const TopoDS_Shape& subShape);
/*!
- * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
- * \param F - the face
- * \retval bool - return true if the face is periodic
- *
- * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
- * SetSubShape()
+ * \brief Return ID of the shape set by IsQuadraticSubMesh() or SetSubShape()
+ * \retval int - shape index in SMESHDS
*/
- bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
-
+ int GetSubShapeID() const { return myShapeID; }
/*!
- * \brief Return U on edge
- * \param F - the edge
- * \param n - the node
- * \retval double - resulting U
- *
- * Auxilary function called from GetMediumNode()
+ * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape()
*/
- double GetNodeU(const TopoDS_Edge& E,
- const SMDS_MeshNode* n);
-
+ TopoDS_Shape GetSubShape() const { return myShape; }
- /**
- * Special function for search or creation medium node
+ /*!
+ * Creates a node
*/
- const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const bool force3d);
-
- /**
- * Special function for creation quadratic edge
+ SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0);
+ /*!
+ * Creates quadratic or linear edge
*/
- SMDS_QuadraticEdge* AddQuadraticEdge(const SMDS_MeshNode* n1,
- const SMDS_MeshNode* n2,
- const int id = 0,
- const bool force3d = true);
-
- /**
- * Special function for creation quadratic triangle
+ SMDS_MeshEdge* AddEdge(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const int id = 0,
+ const bool force3d = true);
+ /*!
+ * Creates quadratic or linear triangle
*/
SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const int id=0,
const bool force3d = false);
-
- /**
- * Special function for creation quadratic quadrangle
+ /*!
+ * Creates quadratic or linear quadrangle
*/
SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n4,
const int id = 0,
const bool force3d = false);
-
- /**
- * Special function for creation quadratic tetraahedron
+ /*!
+ * Creates quadratic or linear tetraahedron
*/
SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n4,
const int id = 0,
const bool force3d = true);
-
-
- /**
- * Special function for creation quadratic pyramid
+ /*!
+ * Creates quadratic or linear pyramid
*/
SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n5,
const int id = 0,
const bool force3d = true);
-
- /**
- * Special function for creation quadratic pentahedron
+ /*!
+ * Creates quadratic or linear pentahedron
*/
SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n6,
const int id = 0,
const bool force3d = true);
-
- /**
- * Special function for creation quadratic hexahedron
+ /*!
+ * Creates quadratic or linear hexahedron
*/
SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n8,
const int id = 0,
bool force3d = true);
-
-
/*!
- * \brief Set order of elements to create
- * \param theBuildQuadratic - to build quadratic or not
- *
- * To be used for quadratic elements creation without preceding
- * IsQuadraticSubMesh() or AddQuadraticEdge() call
- */
- void SetKeyIsQuadratic(const bool theBuildQuadratic)
- { myCreateQuadratic = theBuildQuadratic; }
-
- /*!
- * \brief Return myCreateQuadratic flag
- * \retval bool - myCreateQuadratic value
- */
- bool GetIsQuadratic() const { return myCreateQuadratic; }
-
- /*!
- * \brief Set shape to make elements on
- * \param subShape, subShapeID - shape or its ID (==SMESHDS_Mesh::ShapeToIndex(shape))
+ * \brief Return U of the given node on the edge
*/
- void SetSubShape(const int subShapeID);
- void SetSubShape(const TopoDS_Shape& subShape);
-
+ double GetNodeU(const TopoDS_Edge& theEdge,
+ const SMDS_MeshNode* theNode);
/*!
- * \brief Return shape or its ID, on which created elements are added
- * \retval int - shape index in SMESHDS
- *
- * Shape is set by calling either IsQuadraticSubMesh() or SetSubShape()
+ * \brief Return node UV on face
+ * \param inFaceNode - a node of element being created located inside a face
*/
- int GetSubShapeID() const { return myShapeID; }
+ gp_XY GetNodeUV(const TopoDS_Face& F,
+ const SMDS_MeshNode* n,
+ const SMDS_MeshNode* inFaceNode=0) const;
/*!
- * \brief Return shape or its ID, on which created elements are added
- * \retval TopoDS_Shape - shape
+ * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
+ * \retval bool - return true if the face is periodic
*
- * Shape is set by calling either IsQuadraticSubMesh() or SetSubShape()
+ * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
+ * SetSubShape()
*/
- TopoDS_Shape GetSubShape() const { return myShape; }
+ bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
/*!
* \brief Check if shape is a seam edge or it's vertex
*/
bool IsSeamShape(const TopoDS_Shape& subShape) const
{ return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
-
/*!
* \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
* has a seam edge
* \retval bool - true if it has
*/
bool HasSeam() const { return !mySeamShapeIds.empty(); }
-
/*!
* \brief Return index of periodic parametric direction of a closed face
* \retval int - 1 for U, 2 for V direction
*/
int GetPeriodicIndex() const { return myParIndex; }
- protected:
+ /**
+ * Special function for search or creation medium node
+ */
+ const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const bool force3d);
+ /*!
+ * Auxilary function for filling myNLinkNodeMap
+ */
+ void AddNLinkNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n12);
+ /**
+ * Auxilary function for filling myNLinkNodeMap
+ */
+ void AddNLinkNodeMap(const NLinkNodeMap& aMap)
+ { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+
+ /**
+ * Returns myNLinkNodeMap
+ */
+ const NLinkNodeMap& GetNLinkNodeMap() const { return myNLinkNodeMap; }
+
+protected:
/*!
* \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV
private:
- void* myMesh;
-
- int myShapeID;
-
- // Key for creation quadratic faces
- bool myCreateQuadratic;
+ // Forbiden copy constructor
+ SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {};
// special map for using during creation quadratic faces
- NLinkNodeMap myNLinkNodeMap;
+ NLinkNodeMap myNLinkNodeMap;
std::set< int > mySeamShapeIds;
double myPar1, myPar2; // bounds of a closed periodic surface
int myParIndex; // bounds' index (1-U, 2-V)
+
TopoDS_Shape myShape;
+ SMESH_Mesh* myMesh;
+ int myShapeID;
+
+ // to create quadratic elements
+ bool myCreateQuadratic;
+ bool mySetElemOnShape;
};
//===========================================================================
void SMESH_Octree::setBox(const Bnd_B3d* box)
{
- delete myBox;
- myBox=new Bnd_B3d(*box);
+// delete myBox;
+// myBox=new Bnd_B3d(*box);
+ *myBox = *box;
}
//===========================================================================
* \param box - Set box to the 3d Bounding Box of the Octree
*/
//===========================================================================
-void SMESH_Octree::getBox(Bnd_B3d* box)
+void SMESH_Octree::getBox(Bnd_B3d& box)
{
- if(box != NULL)
- delete box;
- box = new Bnd_B3d (*myBox);
+// if(box != NULL)
+// delete box;
+// box = new Bnd_B3d (*myBox);
+ box = *myBox;
}
//===========================================================================
//=================================================================
void SMESH_Octree::buildChildren()
{
- myChildren = new (SMESH_Octree*)[8];
+ myChildren = new SMESH_Octree*[8];
gp_XYZ min = myBox->CornerMin();
gp_XYZ max = myBox->CornerMax();
void setBox(const Bnd_B3d* box);
// Set box to the 3d Bounding Box of the Octree
- void getBox(Bnd_B3d* box);
+ void getBox(Bnd_B3d & box);
// Compute the bigger dimension of the box
static double maxSize(const Bnd_B3d* box);
+ // Return its level
+ int level() const { return myLevel; }
+
protected:
// Constructor for children (has to be implemented in inherited classes)
virtual SMESH_Octree* allocateOctreeChild() = 0;
// Module : SMESH
#include "SMESH_OctreeNode.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
#include <gp_Pnt.hxx>
-#include <SMDS_MeshNode.hxx>
using namespace std;
* \param minBoxSize - Minimal size of the Octree Box
*/
//================================================================
-SMESH_OctreeNode::SMESH_OctreeNode (set<const SMDS_MeshNode*> theNodes, const int maxLevel,
+SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
const int maxNbNodes , const double minBoxSize )
:SMESH_Octree(maxLevel,minBoxSize),
myMaxNbNodes(maxNbNodes),
bool Out = 1 ;
if (precision<=0.)
return !(myBox->IsOut(gp_XYZ(X,Y,Z)));
- Bnd_B3d * BoxWithPrecision = new Bnd_B3d();
+ Bnd_B3d BoxWithPrecision;
getBox(BoxWithPrecision);
- BoxWithPrecision->Enlarge(precision);
- Out=BoxWithPrecision->IsOut(gp_XYZ(X,Y,Z));
- delete BoxWithPrecision;
+ BoxWithPrecision.Enlarge(precision);
+ Out=BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z));
return !(Out);
}
}
}
+//================================================================================
+/*!
+ * \brief Return iterator over children
+ */
+//================================================================================
+
+SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
+{
+ return SMESH_OctreeNodeIteratorPtr
+ ( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
+ ( myChildren, ( isLeaf() ? myChildren : &myChildren[ 8 ] )));
+}
+
+//================================================================================
+/*!
+ * \brief Return nodes iterator
+ */
+//================================================================================
+
+SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator()
+{
+ return SMDS_NodeIteratorPtr
+ ( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator >
+ ( myNodes.begin(), myNodes.end() ));
+}
#include "SMESH_Octree.hxx"
+#include <list>
+#include <set>
+
+#include "SMDS_ElemIterator.hxx"
+
//forward declaration
class SMDS_MeshNode;
+class SMESH_OctreeNode;
-#include <list>
-#include <set>
+typedef SMDS_Iterator<SMESH_OctreeNode*> SMESH_OctreeNodeIterator;
+typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
class SMESH_OctreeNode : public SMESH_Octree{
public:
// Constructor
- SMESH_OctreeNode (set<const SMDS_MeshNode*> theNodes, const int maxLevel = -1,
+ SMESH_OctreeNode (const set<const SMDS_MeshNode*>& theNodes, const int maxLevel = -1,
const int maxNbNodes = 5 , const double minBoxSize = 0.);
//=============================
list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
const double theTolerance = 0.00001, const int maxLevel = -1,
const int maxNbNodes = 5);
-
- protected:
+ /*!
+ * \brief Return iterator over children
+ */
+ SMESH_OctreeNodeIteratorPtr GetChildrenIterator();
+ /*!
+ * \brief Return nodes iterator
+ */
+ SMDS_NodeIteratorPtr GetNodeIterator();
+ /*!
+ * \brief Return nb nodes in a tree
+ */
+ int NbNodes() const { return myNbNodes; }
+
+protected:
//=============================
/*!
myPolyElems.reserve( myIdsOnBoundary.size() );
// make a set of refined elements
- map<int,const SMDS_MeshElement* > avoidSet, elemSet;
+ TIDSortedElemSet avoidSet, elemSet;
std::vector<const SMDS_MeshElement*>::iterator itv = myElements.begin();
for(; itv!=myElements.end(); itv++) {
const SMDS_MeshElement* el = (*itv);
- avoidSet.insert( make_pair(el->GetID(),el) );
+ avoidSet.insert( el );
}
//avoidSet.insert( myElements.begin(), myElements.end() );
SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
if ( face )
{
- avoidSet.insert ( make_pair(face->GetID(),face) );
+ avoidSet.insert ( face );
myPolyElems.push_back( face );
// some links of <face> are split;
while ( eIt->more() )
{
const SMDS_MeshElement* elem = eIt->next();
- if ( !volTool.Set( elem ) || !avoidSet.insert( make_pair(elem->GetID(),elem) ).second )
+ if ( !volTool.Set( elem ) || !avoidSet.insert( elem ).second )
continue; // skip faces or refined elements
// add polyhedron definition
myPolyhedronQuantities.push_back(vector<int> ());
#include "SMESH_subMesh.hxx"
-#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_Hypothesis.hxx"
#include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMDS_SetIterator.hxx"
#include "utilities.h"
#include "OpUtil.hxx"
#include <BRep_Builder.hxx>
-
+#include <BRep_Tool.hxx>
#include <TopExp.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-
-#ifdef _DEBUG_
-#include <gp_Pnt.hxx>
-#include <BRep_Tool.hxx>
-#include <TopoDS.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
-#endif
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <gp_Pnt.hxx>
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx>
+using namespace std;
+
//=============================================================================
/*!
* default constructor:
*/
//=============================================================================
-SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS,
- const TopoDS_Shape & aSubShape)
+SMESH_subMesh::SMESH_subMesh(int Id,
+ SMESH_Mesh * father,
+ SMESHDS_Mesh * meshDS,
+ const TopoDS_Shape & aSubShape)
{
_subShape = aSubShape;
- _meshDS = meshDS;
_subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
_father = father;
_Id = Id;
- _dependenceAnalysed = false;
+ _dependenceAnalysed = _alwaysComputed = false;
if (_subShape.ShapeType() == TopAbs_VERTEX)
{
{
MESSAGE("SMESH_subMesh::~SMESH_subMesh");
// ****
+ DeleteOwnListeners();
}
//=============================================================================
SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
{
- // submesh appears in DS only when a mesher set nodes and elements on it
- if (_subMeshDS==NULL)
- {
- _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
-// if (_subMeshDS==NULL)
-// {
-// MESSAGE("problem... subMesh still empty");
-// }
- }
- return _subMeshDS;
+ // submesh appears in DS only when a mesher set nodes and elements on a shape
+ return _subMeshDS ? _subMeshDS : _subMeshDS = _father->GetMeshDS()->MeshElements(_subShape); // may be null
}
//=============================================================================
SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
{
- if ( !GetSubMeshDS() )
- _meshDS->NewSubMesh( _meshDS->ShapeToIndex( _subShape ) );
-
+ if ( !GetSubMeshDS() ) {
+ SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+ meshDS->NewSubMesh( meshDS->ShapeToIndex( _subShape ) );
+ }
return GetSubMeshDS();
}
SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
{
- const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
- SMESH_subMesh *firstToCompute = 0;
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(true,false);
+ while ( smIt->more() ) {
+ SMESH_subMesh *sm = smIt->next();
+ if ( sm->GetComputeState() == READY_TO_COMPUTE )
+ return sm;
+ }
+ return 0; // nothing to compute
+}
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
- {
- SMESH_subMesh *sm = (*itsub).second;
- bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
- if (readyToCompute)
+//================================================================================
+/*!
+ * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+ * none mesh entity is bound to it (PAL13615, 2nd part)
+ */
+//================================================================================
+
+void SMESH_subMesh::SetIsAlwaysComputed(bool isAlCo)
+{
+ _alwaysComputed = isAlCo;
+ if ( _alwaysComputed )
+ _computeState = COMPUTE_OK;
+ else
+ ComputeStateEngine( CHECK_COMPUTE_STATE );
+}
+
+//=======================================================================
+//function : IsMeshComputed
+//purpose : check if _subMeshDS contains mesh elements
+//=======================================================================
+
+bool SMESH_subMesh::IsMeshComputed() const
+{
+ if ( _alwaysComputed )
+ return true;
+ // algo may bind a submesh not to _subShape, eg 3D algo
+ // sets nodes on SHELL while _subShape may be SOLID
+
+ SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+ int dim = SMESH_Gen::GetShapeDim( _subShape );
+ int type = _subShape.ShapeType();
+ for ( ; type <= TopAbs_VERTEX; type++) {
+ if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
{
- firstToCompute = sm;
- break;
+ TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
+ for ( ; exp.More(); exp.Next() )
+ {
+ if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ))
+ {
+ bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes();
+ if ( computed )
+ return true;
+ }
+ }
}
+ else
+ break;
}
- if (firstToCompute)
- {
- return firstToCompute; // a subMesh of this
- }
- if (_computeState == READY_TO_COMPUTE)
- {
- return this; // this
- }
- return 0; // nothing to compute
+
+ return false;
}
//=============================================================================
bool SMESH_subMesh::SubMeshesComputed()
{
- //MESSAGE("SMESH_subMesh::SubMeshesComputed");
- const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
int myDim = SMESH_Gen::GetShapeDim( _subShape );
int dimToCheck = myDim - 1;
bool subMeshesComputed = true;
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+ // check subMeshes with upper dimension => reverse iteration
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+ while ( smIt->more() )
{
- SMESH_subMesh *sm = (*itsub).second;
+ SMESH_subMesh *sm = smIt->next();
+ if ( sm->_alwaysComputed )
+ continue;
const TopoDS_Shape & ss = sm->GetSubShape();
// MSV 07.04.2006: restrict checking to myDim-1 only. Ex., there is no sense
// in checking of existence of edges if the algo needs only faces. Moreover,
// degenerated edges may have no submesh, as after computing NETGEN_2D.
int dim = SMESH_Gen::GetShapeDim( ss );
if (dim < dimToCheck)
- continue;
+ break; // the rest subMeshes are all of less dimension
SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
- // PAL10974.
- // There are some tricks with compute states, e.g. Penta_3D leaves
- // one face with READY_TO_COMPUTE state in order to be able to
- // recompute 3D when a locale triangle hypo changes (see PAL7428).
- // So we check if mesh is really present
bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
- (ds && ( ds->GetNodes()->more() || ds->GetElements()->more() )));
+ (ds && ( ds->NbNodes() || ds->NbElements() )));
if (!computeOk)
{
int type = ss.ShapeType();
bool SMESH_subMesh::SubMeshesReady()
{
- MESSAGE("SMESH_subMesh::SubMeshesReady");
- const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
bool subMeshesReady = true;
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
- {
- SMESH_subMesh *sm = (*itsub).second;
- bool computeOk = ((sm->GetComputeState() == COMPUTE_OK)
- || (sm->GetComputeState() == READY_TO_COMPUTE));
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+ while ( smIt->more() ) {
+ SMESH_subMesh *sm = smIt->next();
+ bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
+ sm->GetComputeState() == READY_TO_COMPUTE);
if (!computeOk)
{
subMeshesReady = false;
*/
//=============================================================================
-const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn()
+const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
{
if (_dependenceAnalysed)
return _mapDepend;
// hypothesis
switch ( theShapeType ) {
+ case TopAbs_VERTEX:
case TopAbs_EDGE:
case TopAbs_FACE:
case TopAbs_SOLID:
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
- int dim = SMESH_Gen::GetShapeDim(_subShape);
+ SMESHDS_Mesh* meshDS =_father->GetMeshDS();
+ SMESH_Gen* gen =_father->GetGen();
+ SMESH_Algo* algo = 0;
- if (dim < 1)
+ if (_subShape.ShapeType() == TopAbs_VERTEX )
{
- _algoState = HYP_OK;
- if (event == ADD_HYP || event == ADD_ALGO)
- return SMESH_Hypothesis::HYP_BAD_DIM; // do not allow to assign any hyp
- else
- return SMESH_Hypothesis::HYP_OK;
+ if ( anHyp->GetDim() != 0) {
+ if (event == ADD_HYP || event == ADD_ALGO)
+ return SMESH_Hypothesis::HYP_BAD_DIM;
+ else
+ return SMESH_Hypothesis::HYP_OK;
+ }
+ // 0D hypothesis
+ else if ( _algoState == HYP_OK ) { // update default _algoState
+ _algoState = NO_ALGO;
+ algo = gen->GetAlgo(*_father, _subShape);
+ if ( algo ) {
+ _algoState = MISSING_HYP;
+ if ( algo->CheckHypothesis(*_father,_subShape, aux_ret))
+ _algoState = HYP_OK;
+ }
+ }
}
- SMESH_Gen* gen =_father->GetGen();
- SMESH_Algo* algo = 0;
int oldAlgoState = _algoState;
- bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
- // in ComputeStateEngine
+ bool modifiedHyp = (event == MODIF_HYP); // if set to true, force event MODIF_ALGO_STATE
+
+ bool isApplicableHyp = IsApplicableHypotesis( anHyp );
- // ----------------------
- // check mesh conformity
- // ----------------------
- if (event == ADD_ALGO)
+ if (event == ADD_ALGO || event == ADD_FATHER_ALGO)
{
- if (IsApplicableHypotesis( anHyp ) &&
- !_father->IsNotConformAllowed() &&
- !IsConform( static_cast< SMESH_Algo* >( anHyp )))
+ // -------------------------------------------
+ // check if a shape needed by algo is present
+ // -------------------------------------------
+ algo = static_cast< SMESH_Algo* >( anHyp );
+ if ( !_father->HasShapeToMesh() && algo->NeedShape() )
+ return SMESH_Hypothesis::HYP_BAD_GEOMETRY;
+ // ----------------------
+ // check mesh conformity
+ // ----------------------
+ if (isApplicableHyp && !_father->IsNotConformAllowed() && !IsConform( algo ))
return SMESH_Hypothesis::HYP_NOTCONFORM;
}
// ----------------------------------
if (event == ADD_HYP || event == ADD_ALGO)
{
- if ( ! CanAddHypothesis( anHyp ))
+ if ( ! CanAddHypothesis( anHyp )) // check dimension
return SMESH_Hypothesis::HYP_BAD_DIM;
if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
- if ( !_meshDS->AddHypothesis(_subShape, anHyp))
+ if ( !meshDS->AddHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
// Serve Propagation of 1D hypothesis
+ // NOTE: it is possible to re-implement Propagation using EventListener
if (event == ADD_HYP) {
bool isPropagationOk = true;
bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 );
// --------------------------
if (event == REMOVE_HYP || event == REMOVE_ALGO)
{
- if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
+ if (!meshDS->RemoveHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_OK; // nothing changes
// Serve Propagation of 1D hypothesis
+ // NOTE: it is possible to re-implement Propagation using EventListener
if (event == REMOVE_HYP)
{
bool isPropagationOk = true;
// ------------------
// analyse algo state
// ------------------
- if (!IsApplicableHypotesis( anHyp ))
+ if (!isApplicableHyp)
return ret; // not applicable hypotheses do not change algo state
switch (_algoState)
if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) {
- _meshDS->RemoveHypothesis(_subShape, anHyp);
+ meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret;
}
else
break;
}
case REMOVE_HYP:
- break;
case REMOVE_ALGO:
- break;
case ADD_FATHER_HYP:
break;
case ADD_FATHER_ALGO: { // Algo just added in father
}
break;
}
+ case MODIF_HYP: break;
default:
ASSERT(0);
break;
if ( algo->CheckHypothesis((*_father),_subShape, ret ))
SetAlgoState(HYP_OK);
if (SMESH_Hypothesis::IsStatusFatal( ret ))
- _meshDS->RemoveHypothesis(_subShape, anHyp);
+ meshDS->RemoveHypothesis(_subShape, anHyp);
else if (!_father->IsUsedHypothesis( anHyp, this ))
{
- _meshDS->RemoveHypothesis(_subShape, anHyp);
+ meshDS->RemoveHypothesis(_subShape, anHyp);
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
}
break;
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) {
- _meshDS->RemoveHypothesis(_subShape, anHyp);
+ meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret;
}
else
}
break;
}
+ case MODIF_HYP: // assigned hypothesis value may become good
case ADD_FATHER_HYP: {
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if (SMESH_Hypothesis::IsStatusFatal( ret ))
{
MESSAGE("do not add extra hypothesis");
- _meshDS->RemoveHypothesis(_subShape, anHyp);
+ meshDS->RemoveHypothesis(_subShape, anHyp);
}
else
{
}
break;
}
+ case MODIF_HYP: // hypothesis value may become bad
case ADD_FATHER_HYP: { // new father hypothesis ?
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
break;
}
- if ( _algoState != oldAlgoState )
+ // detect algorithm hiding
+ //
+ if ( ret == SMESH_Hypothesis::HYP_OK &&
+ ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
+ algo->GetName() == anHyp->GetName() )
{
- if (_algoState == HYP_OK )
- algo->SetEventListener( this );
- if ( oldAlgoState == HYP_OK )
- DeleteOwnListeners();
+ // is algo hidden?
+ SMESH_Gen* gen = _father->GetGen();
+ TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
+ for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
+ if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
+ if ( !upperAlgo->NeedDescretBoundary() )
+ ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
+ }
+ // is algo hiding?
+ if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDescretBoundary() ) {
+ map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
+ for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
+ if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+ ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
+ }
}
+
+ bool stateChange = ( _algoState != oldAlgoState );
+
+ if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
+ algo->SetEventListener( this );
+
NotifyListenersOnEvent( event, ALGO_EVENT, anHyp );
- if (_algoState != oldAlgoState || modifiedHyp)
+ if ( stateChange && oldAlgoState == HYP_OK ) { // hyp becomes KO
+ DeleteOwnListeners();
+ if (_subShape.ShapeType() == TopAbs_VERTEX ) {
+ // restore default states
+ _algoState = HYP_OK;
+ _computeState = READY_TO_COMPUTE;
+ }
+ }
+
+ if (stateChange || modifiedHyp)
ComputeStateEngine(MODIF_ALGO_STATE);
return ret;
}
-
//=======================================================================
//function : IsConform
//purpose : check if a conform mesh will be produced by the Algo
bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
{
// MESSAGE( "SMESH_subMesh::IsConform" );
-
if ( !theAlgo ) return false;
+ // Suppose that theAlgo is applicable to _subShape, do not check it here
+ //if ( !IsApplicableHypotesis( theAlgo )) return false;
+
// check only algo that doesn't NeedDescretBoundary(): because mesh made
// on a sub-shape will be ignored by theAlgo
- if ( theAlgo->NeedDescretBoundary() )
+ if ( theAlgo->NeedDescretBoundary() ||
+ !theAlgo->OnlyUnaryInput() ) // all adjacent shapes will be meshed by this algo?
return true;
SMESH_Gen* gen =_father->GetGen();
// only local algo is to be checked
- if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
+ //if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
+ if ( _subShape.ShapeType() == _father->GetMeshDS()->ShapeToMesh().ShapeType() )
return true;
// check algo attached to adjacent shapes
// check algo attached to smAdjacent
SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
if (algo &&
- //algo != theAlgo &&
- !algo->NeedDescretBoundary() /*&&
- !gen->IsGlobalHypothesis( algo, *_father )*/)
+ !algo->NeedDescretBoundary() &&
+ algo->OnlyUnaryInput())
return false; // NOT CONFORM MESH WILL BE PRODUCED
}
}
SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
SMESH_Hypothesis * anHyp)
{
- //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
//EAP: a wire (dim==1) should notify edges (dim==1)
//EAP: int dim = SMESH_Gen::GetShapeDim(_subShape);
if (_subShape.ShapeType() < TopAbs_EDGE ) // wire,face etc
{
- const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
- {
- SMESH_subMesh *sm = (*itsub).second;
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+ while ( smIt->more() ) {
SMESH_Hypothesis::Hypothesis_Status ret2 =
- sm->AlgoStateEngine(event, anHyp);
+ smIt->next()->AlgoStateEngine(event, anHyp);
if ( ret2 > ret )
ret = ret2;
}
void SMESH_subMesh::CleanDependsOn()
{
- //MESSAGE("SMESH_subMesh::CleanDependsOn");
-
- const map < int, SMESH_subMesh * >&dependson = DependsOn();
- map < int, SMESH_subMesh * >::const_iterator its;
- for (its = dependson.begin(); its != dependson.end(); its++)
- {
- SMESH_subMesh *sm = (*its).second;
- sm->ComputeStateEngine(CLEAN);
- }
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ smIt->next()->ComputeStateEngine(CLEAN);
}
//=============================================================================
while (itn->more()) {
const SMDS_MeshNode * node = itn->next();
//MESSAGE( " RM node: "<<node->GetID());
- //meshDS->RemoveNode(node);
- meshDS->RemoveFreeNode(node, subMeshDS);
+ if ( node->NbInverseNodes() == 0 )
+ meshDS->RemoveFreeNode(node, subMeshDS);
+ else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
+ meshDS->RemoveNode(node);
}
}
}
bool SMESH_subMesh::ComputeStateEngine(int event)
{
+ _computeError.reset();
+
//MESSAGE("SMESH_subMesh::ComputeStateEngine");
//SCRUTE(_computeState);
//SCRUTE(event);
- int dim = SMESH_Gen::GetShapeDim(_subShape);
-
- if (dim < 1)
+ if (_subShape.ShapeType() == TopAbs_VERTEX)
{
- if ( IsMeshComputed() )
+ _computeState = READY_TO_COMPUTE;
+ SMESHDS_SubMesh* smDS = GetSubMeshDS();
+ if ( smDS && smDS->NbNodes() ) {
_computeState = COMPUTE_OK;
- else
- _computeState = READY_TO_COMPUTE;
+ }
+ else if ( event == COMPUTE && !_alwaysComputed ) {
+ const TopoDS_Vertex & V = TopoDS::Vertex( _subShape );
+ gp_Pnt P = BRep_Tool::Pnt(V);
+ if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) {
+ _father->GetMeshDS()->SetNodeOnVertex(n,_Id);
+ _computeState = COMPUTE_OK;
+ }
+ }
+ if ( event == MODIF_ALGO_STATE )
+ CleanDependants();
return true;
}
SMESH_Gen *gen = _father->GetGen();
SMESH_Algo *algo = 0;
bool ret = true;
SMESH_Hypothesis::Hypothesis_Status hyp_status;
- algo_state oldAlgoState = (algo_state) GetAlgoState();
+ //algo_state oldAlgoState = (algo_state) GetAlgoState();
switch (_computeState)
{
case NOT_READY:
switch (event)
{
- case MODIF_HYP:
case MODIF_ALGO_STATE:
algo = gen->GetAlgo((*_father), _subShape);
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
- if (algo)
- {
- ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
- if (ret)
- _computeState = READY_TO_COMPUTE;
- }
- if ( _computeState == READY_TO_COMPUTE )
- SetAlgoState(HYP_OK);
- else
- SetAlgoState(MISSING_HYP);
+ if ( _algoState == HYP_OK )
+ _computeState = READY_TO_COMPUTE;
break;
case COMPUTE: // nothing to do
break;
case SUBMESH_COMPUTED: // nothing to do
break;
case SUBMESH_RESTORED:
- ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ ComputeSubMeshStateEngine( SUBMESH_RESTORED );
break;
case MESH_ENTITY_REMOVED:
break;
case READY_TO_COMPUTE:
switch (event)
{
- case MODIF_HYP:
case MODIF_ALGO_STATE:
- algo = gen->GetAlgo((*_father), _subShape);
- if (algo && !algo->NeedDescretBoundary())
- CleanDependsOn(); // clean sub-meshes with event CLEAN
_computeState = NOT_READY;
+ algo = gen->GetAlgo((*_father), _subShape);
if (algo)
{
- ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
- if (ret) {
- SetAlgoState(HYP_OK); // it might be KO if BAD_PARAM_VALUE
+ if (!algo->NeedDescretBoundary())
+ CleanDependsOn(); // clean sub-meshes with event CLEAN
+ if ( _algoState == HYP_OK )
_computeState = READY_TO_COMPUTE;
- }
- else
- SetAlgoState(MISSING_HYP);
}
break;
case COMPUTE:
break;
}
// check submeshes needed
- if (algo->NeedDescretBoundary())
- ret = SubMeshesComputed();
- if (!ret)
- {
- MESSAGE("Some SubMeshes not computed");
- _computeState = FAILED_TO_COMPUTE;
- break;
+ if (_father->HasShapeToMesh() ) {
+ bool subComputed = SubMeshesComputed();
+ ret = ( algo->NeedDescretBoundary() ? subComputed :
+ ( !subComputed || _father->IsNotConformAllowed() ));
+ if (!ret) {
+ _computeState = FAILED_TO_COMPUTE;
+ if ( !algo->NeedDescretBoundary() )
+ _computeError =
+ SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,"Unexpected submesh",algo);
+ break;
+ }
}
// compute
CleanDependants();
RemoveSubMeshElementsAndNodes();
- {
- try {
+ ret = false;
+ _computeState = FAILED_TO_COMPUTE;
+ _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+ try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
+ OCC_CATCH_SIGNALS;
#endif
- if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
- ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
- else
- ret = algo->Compute((*_father), _subShape);
- }
- catch (Standard_Failure) {
- MESSAGE( "Exception in algo->Compute() ");
- ret = false;
- }
- }
+ algo->InitComputeError();
+ if ( !_father->HasShapeToMesh() ) // no shape
+ {
+ SMESH_MesherHelper helper( *_father );
+ helper.SetSubShape( _subShape );
+ helper.SetElementsOnShape( true );
+ ret = algo->Compute(*_father, &helper );
+ }
+ else
+ {
+ if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) {
+ ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
+ break;
+ }
+ else {
+ ret = algo->Compute((*_father), _subShape);
+ }
+ }
+ if ( !ret )
+ _computeError = algo->GetComputeError();
+ }
+ catch (Standard_Failure& exc) {
+ if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+ _computeError->myName = COMPERR_OCC_EXCEPTION;
+ _computeError->myComment = exc.GetMessageString();
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+ _computeError->myName = COMPERR_SLM_EXCEPTION;
+ _computeError->myComment = S_ex.what();
+ }
+ catch ( std::bad_alloc& exc ) {
+ if ( _computeError ) {
+ _computeError->myName = COMPERR_MEMORY_PB;
+ _computeError->myComment = exc.what();
+ }
+ throw exc;
+ }
+ catch ( std::exception& exc ) {
+ if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+ _computeError->myName = COMPERR_STD_EXCEPTION;
+ _computeError->myComment = exc.what();
+ }
+ catch ( ... ) {
+ if ( _computeError )
+ _computeError->myName = COMPERR_EXCEPTION;
+ else
+ ret = false;
+ }
+ if ( ret && _computeError && !_computeError->IsOK() ) {
+ ret = false;
+ }
+ if (ret) { // check if anything was built
+ ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
+ }
if (!ret)
{
- MESSAGE("problem in algo execution: failed to compute");
- // release ALGO from responsibilty of partially built mesh
- RemoveSubMeshElementsAndNodes();
- _computeState = FAILED_TO_COMPUTE;
- if (!algo->NeedDescretBoundary())
- UpdateSubMeshState( FAILED_TO_COMPUTE );
-
-#ifdef _DEBUG_
- // Show vertices location of a failed shape
- cout << algo->GetName() << " failed on shape with the following vertices:" << endl;
- TopTools_IndexedMapOfShape vMap;
- TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
- for ( int iv = 1; iv <= vMap.Extent(); ++iv ) {
- gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
- cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
- }
-#endif
- break;
+ // Set _computeError
+ if ( !_computeError )
+ _computeError = SMESH_ComputeError::New();
+ if ( _computeError->IsOK() )
+ _computeError->myName = COMPERR_ALGO_FAILED;
}
else
{
- _computeState = COMPUTE_OK;
+ _computeError.reset();
UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
- if (!algo->NeedDescretBoundary())
- UpdateSubMeshState( COMPUTE_OK );
}
+ if ( !algo->NeedDescretBoundary() )
+ UpdateSubMeshState( ret ? COMPUTE_OK : FAILED_TO_COMPUTE );
+ CheckComputeError( algo );
}
break;
case CLEAN:
// check if a mesh is already computed that may
// happen after retrieval from a file
ComputeStateEngine( CHECK_COMPUTE_STATE );
- ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ ComputeSubMeshStateEngine( SUBMESH_RESTORED );
+ algo = gen->GetAlgo(*_father, _subShape);
+ if (algo) algo->SubmeshRestored( this );
break;
case MESH_ENTITY_REMOVED:
break;
case COMPUTE_OK:
switch (event)
{
- case MODIF_HYP:
case MODIF_ALGO_STATE:
ComputeStateEngine( CLEAN );
algo = gen->GetAlgo((*_father), _subShape);
CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN
RemoveSubMeshElementsAndNodes();
_computeState = NOT_READY;
- algo = gen->GetAlgo((*_father), _subShape);
- if (algo)
- {
- ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
- if (ret)
- _computeState = READY_TO_COMPUTE;
- else
- SetAlgoState(MISSING_HYP);
- }
+ if ( _algoState == HYP_OK )
+ _computeState = READY_TO_COMPUTE;
break;
case SUBMESH_COMPUTED: // nothing to do
break;
case SUBMESH_RESTORED:
ComputeStateEngine( CHECK_COMPUTE_STATE );
- ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ ComputeSubMeshStateEngine( SUBMESH_RESTORED );
+ algo = gen->GetAlgo(*_father, _subShape);
+ if (algo) algo->SubmeshRestored( this );
break;
case MESH_ENTITY_REMOVED:
UpdateDependantsState( CHECK_COMPUTE_STATE );
case FAILED_TO_COMPUTE:
switch (event)
{
- case MODIF_HYP:
- if (_algoState == HYP_OK)
- _computeState = READY_TO_COMPUTE;
- else
- _computeState = NOT_READY;
- break;
case MODIF_ALGO_STATE:
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
case CLEAN:
CleanDependants(); // submeshes dependent on me should be cleaned as well
RemoveSubMeshElementsAndNodes();
- if (_algoState == HYP_OK)
- _computeState = READY_TO_COMPUTE;
- else
- _computeState = NOT_READY;
break;
case SUBMESH_COMPUTED: // allow retry compute
if (_algoState == HYP_OK)
_computeState = NOT_READY;
break;
case SUBMESH_RESTORED:
- ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ ComputeSubMeshStateEngine( SUBMESH_RESTORED );
break;
case MESH_ENTITY_REMOVED:
break;
break;
}
- if ( _algoState != oldAlgoState || event == MODIF_HYP )
- {
- if ( oldAlgoState == HYP_OK )
- DeleteOwnListeners();
- if (_algoState == HYP_OK && algo )
- algo->SetEventListener( this );
- }
NotifyListenersOnEvent( event, COMPUTE_EVENT );
- //SCRUTE(_computeState);
return ret;
}
+//=======================================================================
+/*!
+ * \brief Update compute_state by _computeError
+ */
+//=======================================================================
+
+bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo)
+{
+ bool noErrors = ( !_computeError || _computeError->IsOK() );
+ if ( !noErrors )
+ {
+ if ( !_computeError->myAlgo )
+ _computeError->myAlgo = theAlgo;
+
+ // Show error
+ SMESH_Comment text;
+ text << theAlgo->GetName() << " failed on subshape " << _Id << " with error ";
+ if (_computeError->IsCommon() )
+ text << _computeError->CommonName();
+ else
+ text << _computeError->myName;
+ if ( _computeError->myComment.size() > 0 )
+ text << " \"" << _computeError->myComment << "\"";
+
+#ifdef _DEBUG_
+ cout << text << endl;
+ // Show vertices location of a failed shape
+ cout << "Subshape vertices (first 10):" << endl;
+ TopTools_IndexedMapOfShape vMap;
+ TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
+ for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) {
+ gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
+ cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
+ }
+#else
+ INFOS( text );
+#endif
+ _computeState = FAILED_TO_COMPUTE;
+ }
+ else
+ {
+ _computeState = COMPUTE_OK;
+ }
+ // Check state of submeshes
+ if ( !theAlgo->NeedDescretBoundary() /*&& theAlgo->OnlyUnaryInput()*/ ) {
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ if ( !smIt->next()->CheckComputeError( theAlgo ))
+ noErrors = false;
+ }
+ return noErrors;
+}
+
//=======================================================================
//function : ApplyToCollection
//purpose : Apply theAlgo to all subshapes in theCollection
MESSAGE("SMESH_subMesh::ApplyToCollection");
ASSERT ( !theAlgo->NeedDescretBoundary() );
- bool ret = false;
+ if ( _computeError )
+ _computeError->myName = COMPERR_OK;
-
- ret = theAlgo->Compute( *_father, theCollection );
+ bool ok = theAlgo->Compute( *_father, theCollection );
// set _computeState of subshapes
TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
for ( ; anExplorer.More(); anExplorer.Next() )
{
- const TopoDS_Shape& aSubShape = anExplorer.Current();
- SMESH_subMesh* subMesh = _father->GetSubMeshContaining( aSubShape );
- if ( subMesh )
+ if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() ))
{
- if (ret)
+ bool localOK = subMesh->CheckComputeError( theAlgo );
+ if ( !ok && localOK && !subMesh->IsMeshComputed() )
{
- subMesh->_computeState = COMPUTE_OK;
- subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
- subMesh->UpdateSubMeshState( COMPUTE_OK );
- }
- else
- {
- subMesh->_computeState = FAILED_TO_COMPUTE;
+ subMesh->_computeError = theAlgo->GetComputeError();
+ if ( subMesh->_computeError->IsOK() )
+ _computeError = SMESH_ComputeError::New(COMPERR_ALGO_FAILED);
+ localOK = CheckComputeError( theAlgo );
}
+ if ( localOK )
+ subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
+ subMesh->UpdateSubMeshState( localOK ? COMPUTE_OK : FAILED_TO_COMPUTE );
}
}
- return ret;
+
+ return true;
}
void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
{
- const map<int, SMESH_subMesh*>& smMap = DependsOn();
- map<int, SMESH_subMesh*>::const_iterator itsub;
- for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
- {
- SMESH_subMesh* sm = (*itsub).second;
- sm->_computeState = theState;
- }
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ smIt->next()->_computeState = theState;
}
//=======================================================================
void SMESH_subMesh::ComputeSubMeshStateEngine(int event)
{
- const map<int, SMESH_subMesh*>& smMap = DependsOn();
- map<int, SMESH_subMesh*>::const_iterator itsub;
- for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
- {
- SMESH_subMesh* sm = (*itsub).second;
- sm->ComputeStateEngine(event);
- }
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ smIt->next()->ComputeStateEngine(event);
}
//=======================================================================
}
}
-//=======================================================================
-//function : IsMeshComputed
-//purpose : check if _subMeshDS contains mesh elements
-//=======================================================================
-
-bool SMESH_subMesh::IsMeshComputed() const
-{
- // algo may bind a submesh not to _subShape, eg 3D algo
- // sets nodes on SHELL while _subShape may be SOLID
-
- int dim = SMESH_Gen::GetShapeDim( _subShape );
- int type = _subShape.ShapeType();
- for ( ; type <= TopAbs_VERTEX; type++) {
- if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
- {
- TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
- for ( ; exp.More(); exp.Next() )
- {
- SMESHDS_SubMesh * smDS = _meshDS->MeshElements( exp.Current() );
- if ( smDS && ( smDS->NbElements() || smDS->NbNodes()))
- return true;
- }
- }
- else
- break;
- }
-
- return false;
-}
-
-
//=======================================================================
//function : GetCollection
//purpose : return a shape containing all sub-shapes of the MainShape that can be
{
const TopoDS_Shape& S = anExplorer.Current();
SMESH_subMesh* subMesh = _father->GetSubMesh( S );
- SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
-
- if (subMesh->GetComputeState() == READY_TO_COMPUTE &&
- anAlgo == theAlgo &&
- anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
+ if ( subMesh == this )
{
aBuilder.Add( aCompound, S );
}
+ else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
+ {
+ SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
+ if (anAlgo == theAlgo &&
+ anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
+ aBuilder.Add( aCompound, S );
+ }
}
return aCompound;
//=======================================================================
//function : CheckConcurentHypothesis
//purpose : check if there are several applicable hypothesis attached to
-// ansestors
+// ancestors
//=======================================================================
SMESH_Hypothesis::Hypothesis_Status
void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* data)
{
- myEventListeners.insert( make_pair( listener, data ));
+ map< EventListener*, EventListenerData* >::iterator l_d =
+ myEventListeners.find( listener );
+ if ( l_d != myEventListeners.end() ) {
+ if ( l_d->second && l_d->second->IsDeletable() )
+ delete l_d->second;
+ l_d->second = data;
+ }
+ else
+ myEventListeners.insert( make_pair( listener, data ));
}
//================================================================================
map< EventListener*, EventListenerData* >::iterator l_d =
myEventListeners.find( listener );
if ( l_d != myEventListeners.end() ) {
- if ( l_d->first->IsDeletable() ) delete l_d->first;
- if ( l_d->second->IsDeletable() ) delete l_d->second;
+ if ( l_d->first && l_d->first->IsDeletable() ) delete l_d->first;
+ if ( l_d->second && l_d->second->IsDeletable() ) delete l_d->second;
myEventListeners.erase( l_d );
}
}
const int eventType,
SMESH_subMesh* subMesh,
EventListenerData* data,
- SMESH_Hypothesis* /*hyp*/)
+ const SMESH_Hypothesis* /*hyp*/)
{
if ( data && !data->mySubMeshes.empty() &&
eventType == SMESH_subMesh::COMPUTE_EVENT)
}
}
}
+
+namespace {
+
+ //================================================================================
+ /*!
+ * \brief Iterator over submeshes and optionally prepended or appended one
+ */
+ //================================================================================
+
+ struct _Iterator : public SMDS_Iterator<SMESH_subMesh*>
+ {
+ _Iterator(SMDS_Iterator<SMESH_subMesh*>* subIt,
+ SMESH_subMesh* prepend,
+ SMESH_subMesh* append): myIt(subIt),myAppend(append)
+ {
+ myCur = prepend ? prepend : myIt->more() ? myIt->next() : 0;
+ }
+ /// Return true if and only if there are other object in this iterator
+ virtual bool more()
+ {
+ return myCur;
+ }
+ /// Return the current object and step to the next one
+ virtual SMESH_subMesh* next()
+ {
+ SMESH_subMesh* res = myCur;
+ if ( myIt->more() ) { myCur = myIt->next(); }
+ else { myCur = myAppend; myAppend = 0; }
+ return res;
+ }
+ /// ~
+ ~_Iterator()
+ { delete myIt; }
+ ///
+ SMESH_subMesh *myAppend, *myCur;
+ SMDS_Iterator<SMESH_subMesh*> *myIt;
+ };
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator on the submeshes this one depends on
+ * \param includeSelf - this submesh to be returned also
+ * \param reverse - if true, complex shape submeshes go first
+ */
+//================================================================================
+
+SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeSelf,
+ const bool reverse)
+{
+ SMESH_subMesh *prepend=0, *append=0;
+ if ( includeSelf ) {
+ if ( reverse ) prepend = this;
+ else append = this;
+ }
+ typedef map < int, SMESH_subMesh * > TMap;
+ if ( reverse )
+ {
+ return SMESH_subMeshIteratorPtr
+ ( new _Iterator( new SMDS_mapReverseIterator<TMap>( DependsOn() ), prepend, append ));
+ }
+ {
+ return SMESH_subMeshIteratorPtr
+ ( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
+ }
+}
#include "SMESHDS_Mesh.hxx"
#include "SMESHDS_SubMesh.hxx"
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
+
#include "Utils_SALOME_Exception.hxx"
+
#include <TopoDS_Shape.hxx>
-#include <TColStd_IndexedMapOfTransient.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <set>
#include <list>
#include <map>
class SMESH_Gen;
class SMESH_subMeshEventListener;
class SMESH_subMeshEventListenerData;
+class SMESH_subMesh;
typedef SMESH_subMeshEventListener EventListener;
typedef SMESH_subMeshEventListenerData EventListenerData;
+typedef boost::shared_ptr< SMDS_Iterator<SMESH_subMesh*> > SMESH_subMeshIteratorPtr;
+
+
class SMESH_EXPORT SMESH_subMesh
{
public:
int GetId() const;
- // bool Contains(const TopoDS_Shape & aSubShape)
- // throw (SALOME_Exception);
-
SMESH_Mesh* GetFather() { return _father; }
SMESHDS_SubMesh * GetSubMeshDS();
SMESH_subMesh *GetFirstToCompute();
- const map < int, SMESH_subMesh * >&DependsOn();
+ const map < int, SMESH_subMesh * >& DependsOn();
//const map < int, SMESH_subMesh * >&Dependants();
+ /*!
+ * \brief Return iterator on the submeshes this one depends on
+ */
+ SMESH_subMeshIteratorPtr getDependsOnIterator(const bool includeSelf,
+ const bool complexShapeFirst);
const TopoDS_Shape & GetSubShape() const;
};
enum algo_event
{
- ADD_HYP, ADD_ALGO,
- REMOVE_HYP, REMOVE_ALGO,
- ADD_FATHER_HYP, ADD_FATHER_ALGO,
- REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO
+ ADD_HYP , ADD_ALGO,
+ REMOVE_HYP , REMOVE_ALGO,
+ ADD_FATHER_HYP , ADD_FATHER_ALGO,
+ REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO,
+ MODIF_HYP
};
enum compute_event
{
- MODIF_HYP, MODIF_ALGO_STATE, COMPUTE,
+ MODIF_ALGO_STATE, COMPUTE,
CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED,
MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE
};
* \param listener - the listener to store
* \param data - the listener data to store
* \param where - the submesh to store the listener and it's data
- * \param deleteListener - if true then the listener will be deleted as
- * it is removed from where submesh
*
- * It remembers the submesh where it puts the listener in order to delete
+ * The method remembers the submesh \awhere it puts the listener in order to delete
* them when HYP_OK algo_state is lost
- * After being set, event listener is notified on each event of where submesh.
+ * After being set, event listener is notified on each event of \awhere submesh.
*/
void SetEventListener(EventListener* listener,
EventListenerData* data,
int GetAlgoState() const { return _algoState; }
int GetComputeState() const { return _computeState; };
+ SMESH_ComputeErrorPtr& GetComputeError() { return _computeError; }
void DumpAlgoState(bool isMain);
bool IsMeshComputed() const;
// check if _subMeshDS contains mesh elements
+ /*!
+ * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+ * none mesh entity is bound to it
+ */
+ void SetIsAlwaysComputed(bool isAlCo);
+
+
protected:
// ==================================================================
void InsertDependence(const TopoDS_Shape aSubShape);
void CleanDependsOn();
void SetAlgoState(int state);
+ /*!
+ * \brief Return a shape containing all sub-shapes of the MainShape that can be
+ * meshed at once along with _subShape
+ */
TopoDS_Shape GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo);
- // return a shape containing all sub-shapes of the MainShape that can be
- // meshed at once along with _subShape
+ /*!
+ * \brief Apply theAlgo to all subshapes in theCollection
+ */
bool ApplyToCollection (SMESH_Algo* theAlgo,
const TopoDS_Shape& theCollection);
- // Apply theAlgo to all subshapes in theCollection
+ /*!
+ * \brief Update compute_state by _computeError
+ * \retval bool - false if there are errors
+ */
+ bool CheckComputeError(SMESH_Algo* theAlgo);
+
+ /*!
+ * \brief Return a hypothesis attached to theShape.
+ *
+ * If theHyp is provided, similar but not same hypotheses
+ * is returned; else an applicable ones having theHypType
+ * is returned
+ */
const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape& theShape,
const SMESH_Hypothesis * theHyp,
const int theHypType = 0);
- // return a hypothesis attached to theShape.
- // If theHyp is provided, similar but not same hypotheses
- // is returned; else an applicable ones having theHypType
- // is returned
-
- TopoDS_Shape _subShape;
- SMESHDS_Mesh * _meshDS;
- SMESHDS_SubMesh * _subMeshDS;
- int _Id;
- SMESH_Mesh *_father;
+ //
+
+protected:
+
+ TopoDS_Shape _subShape;
+ SMESHDS_SubMesh * _subMeshDS;
+ SMESH_Mesh * _father;
+ int _Id;
+
map < int, SMESH_subMesh * >_mapDepend;
- bool _dependenceAnalysed;
+ bool _dependenceAnalysed;
+
+ int _algoState;
+ int _computeState;
+ SMESH_ComputeErrorPtr _computeError;
- int _algoState;
- int _computeState;
+ // allow algo->Compute() if a subshape of lower dim is meshed but
+ // none mesh entity is bound to it. Eg StdMeshers_CompositeSegment_1D can
+ // mesh several edges as a whole and leave some of them without mesh entities
+ bool _alwaysComputed;
};
const int eventType,
SMESH_subMesh* subMesh,
SMESH_subMeshEventListenerData* data,
- SMESH_Hypothesis* hyp = 0);
+ const SMESH_Hypothesis* hyp = 0);
};
// ------------------------------------------------------------------
if ( MYDEBUG )
MESSAGE("Info: The same process, update mesh by pointer ");
// just set client mesh pointer to server mesh pointer
- SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
+ //SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
+ CORBA::LongLong pointeur = theMesh->GetMeshPtr();
+ cerr <<"SMESH_Client::SMESH_Client pointeur " << pointeur << endl;
+ SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
+ cerr <<"SMESH_Client::SMESH_Client aMesh " << aMesh << endl;
if(aMesh->GetMeshDS()->IsEmbeddedMode()){
mySMESHDSMesh = aMesh->GetMeshDS();
mySMDSMesh = mySMESHDSMesh;
virtual std::ostream & SaveTo(std::ostream & save)=0;
virtual std::istream & LoadFrom(std::istream & load)=0;
-enum hypothesis_type {PARAM_ALGO, ALGO, ALGO_1D, ALGO_2D, ALGO_3D};
+enum hypothesis_type {PARAM_ALGO, ALGO_0D, ALGO_1D, ALGO_2D, ALGO_3D};
protected:
std::string _name;
//=======================================================================
bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
- const SMESHDS_Hypothesis * H)
+ const SMESHDS_Hypothesis * H)
{
- //list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
-
- if ( !myShapeToHypothesis.IsBound( SS ) )
- myShapeToHypothesis.Bind( SS, list<const SMESHDS_Hypothesis *>() );
-
- list<const SMESHDS_Hypothesis *>& alist = myShapeToHypothesis.ChangeFind( SS );
+ list<const SMESHDS_Hypothesis *>& alist=
+ myShapeToHypothesis[SS.Oriented(TopAbs_FORWARD)]; // ignore orientation of SS
-
+ //Check if the Hypothesis is still present
+ list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
- //Check if the Hypothesis is still present
- list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
+ if (alist.end() != ith) return false;
- for (; ith!=alist.end(); ith++)
- if (H == *ith) return false;
-
- alist.push_back(H);
- return true;
+ alist.push_back(H);
+ return true;
}
//=======================================================================
//purpose :
//=======================================================================
-bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
- const SMESHDS_Hypothesis * H)
+bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
+ const SMESHDS_Hypothesis * H)
{
- /*ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
- if(its!=myShapeToHypothesis.end())
- {
- list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
+ ShapeToHypothesis::iterator its=
+ myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD)); // ignore orientation of S
- for (; ith!=(*its).second.end(); ith++)
- if (H == *ith)
- {
- (*its).second.erase(ith);
- return true;
- }
- }*/
- if ( myShapeToHypothesis.IsBound( S ) )
+ if(its!=myShapeToHypothesis.end())
{
- list<const SMESHDS_Hypothesis *>& alist = myShapeToHypothesis.ChangeFind( S );
- list<const SMESHDS_Hypothesis*>::iterator ith = alist.begin();
-
- for (; ith != alist.end(); ith++)
- if (H == *ith)
- {
- alist.erase(ith);
- return true;
- }
+ list<const SMESHDS_Hypothesis *>& alist=(*its).second;
+ list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
+ if (ith != alist.end())
+ {
+ alist.erase(ith);
+ return true;
+ }
}
- return false;
+ return false;
}
//=======================================================================
//purpose :
//=======================================================================
-const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
- const TopoDS_Shape & S) const
+const list<const SMESHDS_Hypothesis*>&
+SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
{
- if ( myShapeToHypothesis.IsBound(S) )
- return myShapeToHypothesis.Find(S);
+ ShapeToHypothesis::const_iterator its=
+ myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD)); // ignore orientation of S
+ if (its!=myShapeToHypothesis.end())
+ return its->second;
- static list<const SMESHDS_Hypothesis*> empty;
- return empty;
+ static list<const SMESHDS_Hypothesis*> empty;
+ return empty;
}
//=======================================================================
//=======================================================================
bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
{
- return myShapeToHypothesis.IsBound(S);
+ return myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD))!=myShapeToHypothesis.end();
}
//=======================================================================
bool IsEmbeddedMode();
void ShapeToMesh(const TopoDS_Shape & S);
+ TopoDS_Shape ShapeToMesh() const;
bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H);
bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H);
const TopoDS_Shape & S);
void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt,
const TopoDS_Shape & S);
- TopoDS_Shape ShapeToMesh() const;
bool HasMeshElements(const TopoDS_Shape & S);
SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S) const;
SMESHDS_SubMesh * MeshElements(const int Index);
std::list<int> SubMeshIndices();
- const std::map<int,SMESHDS_SubMesh*>& SubMeshes()
+ const std::map<int,SMESHDS_SubMesh*>& SubMeshes() const
{ return myShapeIndexToSubMesh; }
bool HasHypothesis(const TopoDS_Shape & S);
SMESHGUI_ShapeByMeshDlg.cxx \
SMESHGUI_AddQuadraticElementDlg.cxx \
SMESHGUI_ConvToQuadDlg.cxx \
- SMESHGUI_ConvToQuadOp.cxx
+ SMESHGUI_ConvToQuadOp.cxx \
+ SMESHGUI_BuildCompoundDlg.cxx \
+ SMESHGUI_ComputeDlg.cxx \
+ SMESHGUI_MakeNodeAtPointDlg.cxx \
+ SMESHGUI_MeshEditPreview.cxx
MOC_FILES = \
SMESHGUI_moc.cxx \
SMESHGUI_ShapeByMeshDlg_moc.cxx \
SMESHGUI_AddQuadraticElementDlg_moc.cxx \
SMESHGUI_ConvToQuadDlg_moc.cxx \
- SMESHGUI_ConvToQuadOp_moc.cxx
+ SMESHGUI_ConvToQuadOp_moc.cxx \
+ SMESHGUI_BuildCompoundDlg_moc.cxx \
+ SMESHGUI_ComputeDlg_moc.cxx \
+ SMESHGUI_MakeNodeAtPointDlg_moc.cxx
nodist_libSMESH_la_SOURCES= \
$(MOC_FILES)
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : SMESHGUI.cxx
// Author : Nicolas REJNERI
#include "SMESHGUI_RotationDlg.h"
#include "SMESHGUI_SymmetryDlg.h"
#include "SMESHGUI_SewingDlg.h"
-#include "SMESHGUI_MergeNodesDlg.h"
#include "SMESHGUI_EditMeshDlg.h"
#include "SMESHGUI_MeshPatternDlg.h"
#include "SMESHGUI_Selection.h"
#include "SMESHGUI_ConvToQuadOp.h"
#include "SMESHGUI_MeshOp.h"
#include "SMESHGUI_Displayer.h"
+#include "SMESHGUI_MakeNodeAtPointDlg.h"
+#include "SMESHGUI_BuildCompoundDlg.h"
+#include "SMESHGUI_ComputeDlg.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_GEOMGenUtils.h"
#include "SALOMEconfig.h"
#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
// QT Includes
#define INCLUDE_MENUITEM_DEF
if ( !aMesh->_is_nil() ) {
QString aFilter, aTitle = QObject::tr("Export mesh");
QMap<QString, SMESH::MED_VERSION> aFilterMap;
+ QMap<QString, int> aFilterMapSTL;
switch ( theCommandID ) {
case 125:
case 122:
aFilter = QObject::tr("IDEAS files (*.unv)");
}
break;
+ case 140:
+ case 141:
+ {
+ // export STL
+ /*
+ there must be check on others mesh elements not equal triangles
+ */
+ if (aMesh->NbTriangles() < 1) {
+ int aRet = SUIT_MessageBox::warn1
+ (SMESHGUI::desktop(),
+ QObject::tr("SMESH_WRN_WARNING"),
+ QObject::tr("SMESH_EXPORT_STL1").arg(anIObject->getName()),
+ QObject::tr("SMESH_BUT_OK"));
+ return;
+ }
+ if (!(aMesh->NbElements() - aMesh->NbTriangles())) {
+ int aRet = SUIT_MessageBox::warn2
+ (SMESHGUI::desktop(),
+ QObject::tr("SMESH_WRN_WARNING"),
+ QObject::tr("SMESH_EXPORT_STL2").arg(anIObject->getName()),
+ QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"),
+ 0, 1, 0);
+ if (aRet)
+ return;
+ }
+
+ aFilterMapSTL.insert( QObject::tr("STL ASCII (*.stl)"), 1 ); // 1 - ASCII mode
+ aFilterMapSTL.insert( QObject::tr("STL Binary (*.stl)"), 0 ); // 0 - Binary mode
+ }
+ break;
default:
return;
}
QString aFilename;
SMESH::MED_VERSION aFormat;
// Init the parameter with the default value
+ bool aIsASCII_STL = true;
bool toCreateGroups = false;
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
if ( resMgr )
toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
-
- if ( theCommandID != 122 && theCommandID != 125 )
+
+ if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 140 && theCommandID != 141)
+
aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), "", aFilter, aTitle, false);
+
+ else if(theCommandID == 140 || theCommandID == 141) { // Export to STL
+ QStringList filters;
+ QMap<QString, int>::const_iterator it = aFilterMapSTL.begin();
+ for ( ; it != aFilterMapSTL.end(); ++it )
+ filters.push_back( it.key() );
+
+ SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+ fd->setCaption( aTitle );
+ fd->setFilters( filters );
+ fd->setSelectedFilter( QObject::tr("STL ASCII (*.stl)") );
+ bool is_ok = false;
+ while (!is_ok) {
+ fd->exec();
+ aFilename = fd->selectedFile();
+ aIsASCII_STL = (aFilterMapSTL[fd->selectedFilter()]) == 1 ? true: false;
+ is_ok = true;
+ }
+ delete fd;
+ }
else {
QStringList filters;
QMap<QString, SMESH::MED_VERSION>::const_iterator it = aFilterMap.begin();
SUIT_OverrideCursor wc;
try {
+ bool Renumber = false ;
+ // PAL 14172 : Check of we have to renumber or not from the preferences before export
+ if (resMgr)
+ Renumber= resMgr->booleanValue("SMESH","renumbering");
+ if (Renumber){
+ SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+ aMeshEditor->RenumberNodes();
+ aMeshEditor->RenumberElements();
+ if ( SMESHGUI::automaticUpdate() )
+ SMESH::UpdateView();
+ }
switch ( theCommandID ) {
case 125:
case 122:
case 123:
aMesh->ExportUNV( aFilename.latin1() );
break;
+ case 140:
+ case 141:
+ aMesh->ExportSTL( aFilename.latin1(), aIsASCII_STL );
+ break;
default:
break;
}
_PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
if (aMeshSO)
- SMESH::ModifiedMesh(aMeshSO, false);
+ SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
}
else {
IObject = new SALOME_InteractiveObject
//=============================================================================
SMESHGUI::SMESHGUI() :
SalomeApp_Module( "SMESH" )
-{
+{
if ( CORBA::is_nil( myComponentSMESH ) )
{
CORBA::Boolean anIsEmbeddedMode;
case 124:
case 125:
case 126:
+ case 140:
+ case 141:
{
::ExportMeshToFile(theCommandID);
break;
}
}
}
-
- // PAL13338 -->
- if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy) && !automaticUpdate() )
+
+ // PAL13338 + PAL15161 -->
+ if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy) /*&& !automaticUpdate()*/ )
SMESH::UpdateView();
- // PAL13338 <--
+ // PAL13338 + PAL15161 <--
if (anAction == SMESH::eErase) {
SALOME_ListIO l1;
case 701: // COMPUTE MESH
{
- if(checkLock(aStudy)) break;
-
- LightApp_SelectionMgr *Sel = selectionMgr();
- SALOME_ListIO selected; Sel->selectedObjects( selected );
-
- if ( vtkwnd ) {
- int nbSel = selected.Extent();
- if (nbSel != 1){
- SUIT_MessageBox::warn1(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_NO_AVAILABLE_DATA"),
- tr("SMESH_BUT_OK"));
- break;
- }
+ if (checkLock(aStudy)) break;
- SMESH::SMESH_Mesh_var aMesh;
- SMESH::SMESH_subMesh_var aSubMesh;
- Handle(SALOME_InteractiveObject) IObject = selected.First();
- if (IObject->hasEntry()) {
- _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry());
- GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj );
- if ( aShapeObject->_is_nil() ) {
- // imported mesh
- break;
- }
- if( aMeshSObj ) {
- aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(aMeshSObj);
- aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(aMeshSObj);
- if ( !aSubMesh->_is_nil() )
- aMesh = aSubMesh->GetFather();
-
- if (!aMesh->_is_nil()) {
-// if(!GetSMESHGen()->IsReadyToCompute(aMesh,aShapeObject)) {
+ startOperation( 701 );
+// LightApp_SelectionMgr *Sel = selectionMgr();
+// SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+// int nbSel = selected.Extent();
+// if (nbSel != 1) {
+// SUIT_MessageBox::warn1(desktop(),
+// tr("SMESH_WRN_WARNING"),
+// tr("SMESH_WRN_NO_AVAILABLE_DATA"),
+// tr("SMESH_BUT_OK"));
+// break;
+// }
+
+// SMESH::SMESH_Mesh_var aMesh;
+// SMESH::SMESH_subMesh_var aSubMesh;
+// Handle(SALOME_InteractiveObject) IObject = selected.First();
+// if (IObject->hasEntry()) {
+// _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry());
+// GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj );
+// if ( aShapeObject->_is_nil() ) {
+// // imported mesh
+// break;
+// }
+// if ( aMeshSObj ) {
+// aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(aMeshSObj);
+// aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(aMeshSObj);
+// if ( !aSubMesh->_is_nil() )
+// aMesh = aSubMesh->GetFather();
+
+// if (!aMesh->_is_nil()) {
+// SMESH::algo_error_array_var errors = GetSMESHGen()->GetAlgoState(aMesh,aShapeObject);
+// if ( errors->length() > 0 ) {
+// SUIT_MessageBox::warn1(desktop(),
+// tr("SMESH_WRN_WARNING"),
+// SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
+// tr("SMESH_BUT_OK"));
+// break;
+// }
+
+// try {
+// if (GetSMESHGen()->Compute(aMesh, aShapeObject))
+// SMESH::ModifiedMesh(aMeshSObj, true);
+// else
// SUIT_MessageBox::warn1(desktop(),
// tr("SMESH_WRN_WARNING"),
-// tr("SMESH_WRN_MISSING_PARAMETERS"),
+// tr("SMESH_WRN_COMPUTE_FAILED"),
// tr("SMESH_BUT_OK"));
-// break;
+// }
+// catch(const SALOME::SALOME_Exception & S_ex){
+// SalomeApp_Tools::QtCatchCorbaException(S_ex);
+// }
+
+// updateObjBrowser();
+
+// if (automaticUpdate()) {
+// SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(this, /*create*/true);
+// if (aVTKView) {
+// CORBA::Long anId = aStudy->StudyId();
+// TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry());
+// if (aVisualObj) {
+// aVisualObj->Update();
+// SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
+// if (!anActor) {
+// anActor = SMESH::CreateActor(aStudy, IObject->getEntry());
+// if (anActor) {
+// SMESH::DisplayActor(aVTKView, anActor); //apo
+// SMESH::FitAll();
+// }
+// }
+// SMESH::RepaintCurrentView();
+// Sel->setSelectedObjects( selected );
+// }
// }
- SMESH::algo_error_array_var errors = GetSMESHGen()->GetAlgoState(aMesh,aShapeObject);
- if ( errors->length() > 0 ) {
- SUIT_MessageBox::warn1(desktop(),
- tr("SMESH_WRN_WARNING"),
- SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
- tr("SMESH_BUT_OK"));
- break;
- }
- try{
- if (GetSMESHGen()->Compute(aMesh,aShapeObject))
- SMESH::ModifiedMesh(aMeshSObj,true);
- else
- SUIT_MessageBox::warn1(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_COMPUTE_FAILED"),
- tr("SMESH_BUT_OK"));
- }
- catch(const SALOME::SALOME_Exception & S_ex){
- SalomeApp_Tools::QtCatchCorbaException(S_ex);
- }
- }
- }
- }
- CORBA::Long anId = aStudy->StudyId();
- TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,IObject->getEntry());
- if ( automaticUpdate() && aVisualObj){
- aVisualObj->Update();
- SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
- if(!anActor){
- anActor = SMESH::CreateActor(aStudy,IObject->getEntry());
- if(anActor){
- SMESH::DisplayActor(view,anActor); //apo
- SMESH::FitAll();
- }
- }
- SMESH::RepaintCurrentView();
- }
- }
- else{
- SUIT_MessageBox::warn1(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_OK"));
- }
- updateObjBrowser();
- Sel->setSelectedObjects( selected );
- break;
+// }
+// }
+// }
+// }
}
+ break;
case 702: // Create mesh
startOperation( 702 );
case 704: // Edit mesh/sub-mesh
startOperation( 704 );
break;
+ case 710: // Build compound mesh
+ {
+ if (checkLock(aStudy)) break;
+ EmitSignalDeactivateDialog();
+ new SMESHGUI_BuildCompoundDlg( this );
+ }
+ break;
case 407: // DIAGONAL INVERSION
case 408: // Delete diagonal
{
int type;
switch (theCommandID) {
- case 4034:
+ case 4034:
type = QUAD_EDGE; break;
- case 4035:
+ case 4035:
type = QUAD_TRIANGLE; break;
- case 4036:
+ case 4036:
type = QUAD_QUADRANGLE; break;
- case 4037:
+ case 4037:
type = QUAD_TETRAHEDRON; break;
- case 4038:
- type = QUAD_PYRAMID; break;
- case 4039:
- type = QUAD_PENTAHEDRON; break;
+ case 4038:
+ type = QUAD_PYRAMID; break;
+ case 4039:
+ type = QUAD_PENTAHEDRON; break;
case 4040:
type = QUAD_HEXAHEDRON;
break;
if(checkLock(aStudy)) break;
if(vtkwnd) {
EmitSignalDeactivateDialog();
- new SMESHGUI_MergeNodesDlg( this );
+ new SMESHGUI_EditMeshDlg( this, 0 );
}
else {
SUIT_MessageBox::warn1(desktop(),
}
break;
}
- case 4066: // MERGE EQUAL ELEMENTS
+ case 4066: // MERGE EQUAL ELEMENTS
{
if (checkLock(aStudy)) break;
if (vtkwnd) {
EmitSignalDeactivateDialog();
- new SMESHGUI_EditMeshDlg(this,
- "SMESH_MERGE_ELEMENTS_TITLE",
- "ICON_DLG_MERGE_ELEMENTS",
- 1); // MergeEqualElemets
+ new SMESHGUI_EditMeshDlg( this, 1 );
} else {
SUIT_MessageBox::warn1(desktop(),
tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
break;
}
+ case 4067: // MAKE MESH PASS THROUGH POINT
+ startOperation( 4067 );
+ break;
+
case 5105: // Library of selection filters
{
static QValueList<int> aTypes;
createSMESHAction( 121, "DAT" );
createSMESHAction( 122, "MED" );
createSMESHAction( 123, "UNV" );
+ createSMESHAction( 140, "STL" );
createSMESHAction( 124, "EXPORT_DAT" );
createSMESHAction( 125, "EXPORT_MED" );
createSMESHAction( 126, "EXPORT_UNV" );
+ createSMESHAction( 141, "EXPORT_STL" );
createSMESHAction( 33, "DELETE", "ICON_DELETE" );
createSMESHAction( 5105, "SEL_FILTER_LIB" );
createSMESHAction( 701, "COMPUTE", "ICON_COMPUTE" );
createSMESHAction( 702, "CREATE_MESH", "ICON_DLG_INIT_MESH" );
createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" );
createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
+ createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
createSMESHAction( 801, "CREATE_GROUP", "ICON_SMESH_TREE_GROUP" );
createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
createSMESHAction( 803, "EDIT_GROUP", "ICON_EDIT_GROUP" );
createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" );
createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" );
createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" );
+ createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" );
createSMESHAction( 406, "MOVE", "ICON_DLG_MOVE_NODE" );
createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" );
createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" );
createMenu( 121, exportId, -1 );
createMenu( 122, exportId, -1 );
createMenu( 123, exportId, -1 );
+ createMenu( 140, exportId, -1 ); // export to stl STL
createMenu( separator(), fileId, 10 );
createMenu( 702, meshId, -1 );
createMenu( 703, meshId, -1 );
createMenu( 704, meshId, -1 );
+ createMenu( 710, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 701, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 4066, transfId, -1 );
createMenu( 406, modifyId, -1 );
+ createMenu( 4067,modifyId, -1 );
createMenu( 407, modifyId, -1 );
createMenu( 408, modifyId, -1 );
createMenu( 409, modifyId, -1 );
createTool( 702, meshTb );
createTool( 703, meshTb );
createTool( 704, meshTb );
+ createTool( 710, meshTb );
createTool( separator(), meshTb );
createTool( 701, meshTb );
createTool( separator(), meshTb );
createTool( separator(), addRemTb );
createTool( 406, modifyTb );
+ createTool( 4067,modifyTb );
createTool( 407, modifyTb );
createTool( 408, modifyTb );
createTool( 409, modifyTb );
QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( QtxPopupMgr::Selection::defSelCountParam() );
createPopupItem( 125, OB, mesh, only_one_non_empty ); // EXPORT_MED
createPopupItem( 126, OB, mesh, only_one_non_empty ); // EXPORT_UNV
+ createPopupItem( 141, OB, mesh, only_one_non_empty ); // EXPORT_STL
createPopupItem( 33, OB, subMesh + " " + group ); // DELETE
popupMgr()->insert( separator(), -1, 0 );
int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab );
addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" );
-
+ int renumber=addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" );
+
int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab );
float aTol = 1.00000009999999;
std::string aWarning;
SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
- if( name=="selection_object_color" || name=="selection_element_color" ||
+ if( name=="selection_object_color" || name=="selection_element_color" ||
name=="selection_width" || name=="highlight_color" || name=="highlight_width" ||
name=="selection_precision_node" || name=="selection_precision_element" )
SMESH::UpdateSelectionProp( this );
sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x", sbX1);
sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW);
if(sbX1+sbW > aTol){
- aWarning = "Origin and Size Vertical: X+Width > 1\n";
+ aWarning = "Origin and Size Vertical: X+Width > 1\n";
+ sbX1=0.01;
+ sbW=0.05;
aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
}
aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
}
}
-
+
if(aWarning.size() != 0){
aWarning += "The default values are applied instead.";
SUIT_MessageBox::warn1(SMESHGUI::desktop(),
// to do : create operation here
switch( id )
{
+ case 701: // Compute mesh
+ op = new SMESHGUI_ComputeOp();
+ break;
case 702: // Create mesh
op = new SMESHGUI_MeshOp( true, true );
break;
case 417: //convert to quadratic
op = new SMESHGUI_ConvToQuadOp();
break;
+ case 4067: // make mesh pass through point
+ op = new SMESHGUI_MakeNodeAtPointOp();
+ break;
default:
break;
}
#include "utilities.h"
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
// OCCT Includes
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include "utilities.h"
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
// OCCT Includes
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_BuildCompoundDlg.cxx
+// Author : Alexander KOVALEV
+// Module : SMESH
+
+#include "SMESHGUI_BuildCompoundDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_VTKUtils.h"
+
+#include "SMESH_TypeFilter.hxx"
+
+#include "SUIT_Desktop.h"
+#include "SUIT_Session.h"
+#include "SUIT_MessageBox.h"
+#include "SalomeApp_Study.h"
+
+#include "LightApp_Application.h"
+
+#include "SALOME_ListIO.hxx"
+
+#include "utilities.h"
+
+// QT Includes
+#include <qapplication.h>
+#include <qbuttongroup.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qsizepolicy.h>
+#include <qstring.h>
+
+#include <vector>
+#include <set>
+
+//=================================================================================
+// name : SMESHGUI_BuildCompoundDlg
+// Purpose :
+//=================================================================================
+SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule)
+ : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_BuildCompoundDlg", false, WStyle_Customize |
+ WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
+ mySMESHGUI(theModule),
+ mySelectionMgr(SMESH::GetSelectionMgr(theModule))
+{
+ setCaption(tr("SMESH_BUILD_COMPOUND_TITLE"));
+
+ SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+ QPixmap image0 (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_BUILD_COMPOUND_MESH")));
+ QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+ setSizeGripEnabled(TRUE);
+ SMESHGUI_BuildCompoundDlgLayout = new QGridLayout (this);
+ SMESHGUI_BuildCompoundDlgLayout->setSpacing(6);
+ SMESHGUI_BuildCompoundDlgLayout->setMargin(11);
+
+ /***************************************************************/
+ GroupConstructors = new QButtonGroup (this, "GroupConstructors");
+ GroupConstructors->setTitle(tr("COMPOUND" ));
+ GroupConstructors->setExclusive(TRUE);
+ GroupConstructors->setColumnLayout(0, Qt::Vertical);
+ GroupConstructors->layout()->setSpacing(0);
+ GroupConstructors->layout()->setMargin(0);
+ GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout());
+ GroupConstructorsLayout->setAlignment(Qt::AlignTop);
+ GroupConstructorsLayout->setSpacing(6);
+ GroupConstructorsLayout->setMargin(11);
+ Constructor1 = new QRadioButton (GroupConstructors, "Constructor1");
+ Constructor1->setText(tr(""));
+ Constructor1->setPixmap(image0);
+ Constructor1->setChecked(TRUE);
+ GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
+ SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupConstructors, 0, 0);
+
+ /***************************************************************/
+ GroupName = new QGroupBox (this, "GroupName");
+ GroupName->setTitle(tr("RESULT_NAME" ));
+ GroupName->setColumnLayout(0, Qt::Vertical);
+ GroupName->layout()->setSpacing(0);
+ GroupName->layout()->setMargin(0);
+ GroupNameLayout = new QGridLayout (GroupName->layout());
+ GroupNameLayout->setAlignment(Qt::AlignTop);
+ GroupNameLayout->setSpacing(6);
+ GroupNameLayout->setMargin(11);
+ TextLabelName = new QLabel (GroupName, "TextLabelName");
+ TextLabelName->setText(tr("SMESH_NAME"));
+ GroupNameLayout->addWidget(TextLabelName, 0, 0);
+ LineEditName = new QLineEdit (GroupName, "LineEditName");
+ GroupNameLayout->addWidget(LineEditName, 0, 1);
+ SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupName, 1, 0);
+
+ /***************************************************************/
+ GroupArgs = new QGroupBox (this, "GroupArgs");
+ GroupArgs->setTitle(tr("SMESH_ARGUMENTS" ));
+ GroupArgs->setColumnLayout(0, Qt::Vertical);
+ GroupArgs->layout()->setSpacing(0);
+ GroupArgs->layout()->setMargin(0);
+ GroupArgsLayout = new QGridLayout (GroupArgs->layout());
+ GroupArgsLayout->setAlignment(Qt::AlignTop);
+ GroupArgsLayout->setSpacing(6);
+ GroupArgsLayout->setMargin(11);
+
+ TextLabelMeshes = new QLabel (GroupArgs, "TextLabelMeshes");
+ TextLabelMeshes->setText(tr("MESHES"));
+ TextLabelMeshes->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ GroupArgsLayout->addWidget(TextLabelMeshes, 0, 0);
+ SelectButton = new QPushButton (GroupArgs, "SelectButton");
+ SelectButton->setText(tr(""));
+ SelectButton->setPixmap(image1);
+ SelectButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ GroupArgsLayout->addWidget(SelectButton, 0, 1);
+ LineEditMeshes = new QLineEdit (GroupArgs, "LineEditMeshes");
+ LineEditMeshes->setReadOnly(true);
+ GroupArgsLayout->addMultiCellWidget(LineEditMeshes, 0, 0, 2, 3);
+
+ TextLabelUnion = new QLabel (GroupArgs, "TextLabelUnion");
+ TextLabelUnion->setText(tr("PROCESSING_IDENTICAL_GROUPS"));
+ TextLabelUnion->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ GroupArgsLayout->addMultiCellWidget(TextLabelUnion, 1, 1, 0, 2);
+ ComboBoxUnion = new QComboBox(GroupArgs, "ComboBoxUnion");
+ GroupArgsLayout->addMultiCellWidget(ComboBoxUnion, 1, 1, 3, 3);
+
+ CheckBoxMerge = new QCheckBox(GroupArgs, "CheckBoxMerge");
+ CheckBoxMerge->setText(tr("MERGE_NODES_AND_ELEMENTS" ));
+ GroupArgsLayout->addMultiCellWidget(CheckBoxMerge, 2, 2, 0, 3);
+
+ TextLabelTol = new QLabel (GroupArgs, "TextLabelTol");
+ TextLabelTol->setText(tr("SMESH_TOLERANCE"));
+ TextLabelTol->setAlignment(Qt::AlignCenter);
+ GroupArgsLayout->addMultiCellWidget(TextLabelTol, 3, 3, 0, 1);
+ SpinBoxTol = new SMESHGUI_SpinBox (GroupArgs, "SpinBoxTol");
+ SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.1, 6);
+ GroupArgsLayout->addMultiCellWidget(SpinBoxTol, 3, 3, 2, 3);
+
+ SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupArgs, 2, 0);
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox (this, "GroupButtons");
+ GroupButtons->setGeometry(QRect(10, 10, 281, 48));
+ GroupButtons->setTitle(tr("" ));
+ GroupButtons->setColumnLayout(0, Qt::Vertical);
+ GroupButtons->layout()->setSpacing(0);
+ GroupButtons->layout()->setMargin(0);
+ GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
+ GroupButtonsLayout->setAlignment(Qt::AlignTop);
+ GroupButtonsLayout->setSpacing(6);
+ GroupButtonsLayout->setMargin(11);
+ buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
+ buttonHelp->setText(tr("SMESH_BUT_HELP" ));
+ buttonHelp->setAutoDefault(TRUE);
+ GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
+ buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
+ buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
+ buttonCancel->setAutoDefault(TRUE);
+ GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
+ buttonApply = new QPushButton (GroupButtons, "buttonApply");
+ buttonApply->setText(tr("SMESH_BUT_APPLY" ));
+ buttonApply->setAutoDefault(TRUE);
+ GroupButtonsLayout->addWidget(buttonApply, 0, 1);
+ QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ GroupButtonsLayout->addItem(spacer_9, 0, 2);
+ buttonOk = new QPushButton (GroupButtons, "buttonOk");
+ buttonOk->setText(tr("SMESH_BUT_OK" ));
+ buttonOk->setAutoDefault(TRUE);
+ buttonOk->setDefault(TRUE);
+ GroupButtonsLayout->addWidget(buttonOk, 0, 0);
+ SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupButtons, 3, 0);
+
+ myHelpFileName = "building_compounds.htm";
+
+ Init(); // Initialisations
+}
+
+//=================================================================================
+// function : ~SMESHGUI_BuildCompoundDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_BuildCompoundDlg::~SMESHGUI_BuildCompoundDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::Init()
+{
+ GroupName->show();
+ GroupArgs->show();
+ mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+ myMesh = SMESH::SMESH_Mesh::_nil();
+
+ myMeshFilter = new SMESH_TypeFilter (MESH);
+
+ myMeshArray = new SMESH::mesh_array();
+
+ // signals and slots connections
+ connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+ connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
+ connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+ connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+
+ connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
+
+ connect(CheckBoxMerge, SIGNAL(toggled(bool)), this, SLOT(onSelectMerge(bool)));
+
+ connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+
+ connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+ connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()) , this, SLOT(ClickOnCancel()));
+
+ this->show(); // displays Dialog
+
+ LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH")));
+ LineEditMeshes->setFocus();
+
+ ComboBoxUnion->insertItem(tr("UNITE"));
+ ComboBoxUnion->insertItem(tr("RENAME"));
+ ComboBoxUnion->setCurrentItem(0);
+
+ CheckBoxMerge->setChecked(false);
+
+ TextLabelTol->setEnabled(CheckBoxMerge->isChecked());
+ SpinBoxTol->SetValue(1e-05);
+
+ SpinBoxTol->setEnabled(CheckBoxMerge->isChecked());
+
+ mySelectionMgr->clearFilters();
+ mySelectionMgr->installFilter(myMeshFilter);
+
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : GetDefaultName()
+// purpose :
+//=================================================================================
+QString SMESHGUI_BuildCompoundDlg::GetDefaultName(const QString& theOperation)
+{
+ QString aName = "";
+
+ // collect all object names of SMESH component
+ SalomeApp_Study* appStudy =
+ dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
+ if ( !appStudy ) return aName;
+ _PTR(Study) aStudy = appStudy->studyDS();
+
+ std::set<std::string> aSet;
+ _PTR(SComponent) aMeshCompo (aStudy->FindComponent("SMESH"));
+ if (aMeshCompo) {
+ _PTR(ChildIterator) it (aStudy->NewChildIterator(aMeshCompo));
+ _PTR(SObject) obj;
+ for (it->InitEx(true); it->More(); it->Next()) {
+ obj = it->Value();
+ aSet.insert(obj->GetName());
+ }
+ }
+
+ // build a unique name
+ int aNumber = 0;
+ bool isUnique = false;
+ while (!isUnique) {
+ aName = theOperation + "_" + QString::number(++aNumber);
+ isUnique = (aSet.count(aName.latin1()) == 0);
+ }
+
+ return aName;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
+{
+ if (mySMESHGUI->isActiveStudyLocked())
+ return false;
+ if (!myMesh->_is_nil()) {
+ try {
+ QApplication::setOverrideCursor(Qt::waitCursor);
+
+ SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
+ // concatenate meshes
+ SMESH::SMESH_Mesh_var aCompoundMesh =
+ aSMESHGen->Concatenate(myMeshArray,
+ !(ComboBoxUnion->currentItem()),
+ CheckBoxMerge->isChecked(),
+ SpinBoxTol->GetValue());
+
+ SMESH::SetName( SMESH::FindSObject( aCompoundMesh ), LineEditName->text().latin1() );
+ QApplication::restoreOverrideCursor();
+ mySMESHGUI->updateObjBrowser();
+ } catch(...) {
+ return false;
+ }
+
+ LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH")));
+
+ //mySelectionMgr->clearSelected();
+ SMESH::UpdateView();
+ return true;
+ }
+ return false;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnOk()
+{
+ if (ClickOnApply())
+ ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnCancel()
+{
+ //mySelectionMgr->clearSelected();
+ mySelectionMgr->clearFilters();
+ disconnect(mySelectionMgr, 0, this, 0);
+ mySMESHGUI->ResetState();
+ reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnHelp()
+{
+ LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+ if (app)
+ app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+ else {
+ SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
+ QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+ arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
+ QObject::tr("BUT_OK"));
+ }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::SelectionIntoArgument()
+{
+ if (!GroupButtons->isEnabled()) // inactive
+ return;
+
+ QString aString = "";
+
+ SALOME_ListIO aList;
+ mySelectionMgr->selectedObjects(aList);
+ int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+
+ if (nbSel != 0) {
+ myMeshArray->length(nbSel);
+ for (int i = 0; nbSel != 0; i++, nbSel--) {
+ Handle(SALOME_InteractiveObject) IO = aList.First();
+ aList.RemoveFirst();
+ myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+ myMeshArray[i] = myMesh;
+ }
+ }
+ else {
+ myMesh = SMESH::SMESH_Mesh::_nil();
+ aString = "";
+ }
+
+ LineEditMeshes->setText(aString);
+
+ bool isEnabled = (!myMesh->_is_nil());
+ buttonOk->setEnabled(isEnabled);
+ buttonApply->setEnabled(isEnabled);
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::DeactivateActiveDialog()
+{
+ if (GroupConstructors->isEnabled()) {
+ GroupConstructors->setEnabled(false);
+ GroupName->setEnabled(false);
+ GroupArgs->setEnabled(false);
+ GroupButtons->setEnabled(false);
+ mySMESHGUI->ResetState();
+ mySMESHGUI->SetActiveDialogBox(0);
+ }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ActivateThisDialog()
+{
+ /* Emit a signal to deactivate the active dialog */
+ mySMESHGUI->EmitSignalDeactivateDialog();
+ GroupConstructors->setEnabled(true);
+ GroupName->setEnabled(true);
+ GroupArgs->setEnabled(true);
+ GroupButtons->setEnabled(true);
+
+ mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::enterEvent(QEvent* e)
+{
+ if (GroupConstructors->isEnabled())
+ return;
+ ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::closeEvent(QCloseEvent* e)
+{
+ /* same than click on cancel button */
+ this->ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose : caused by ESC key
+//=======================================================================
+void SMESHGUI_BuildCompoundDlg::hideEvent (QHideEvent * e)
+{
+ if (!isMinimized())
+ ClickOnCancel();
+}
+
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::keyPressEvent( QKeyEvent* e )
+{
+ QDialog::keyPressEvent( e );
+ if ( e->isAccepted() )
+ return;
+
+ if ( e->key() == Key_F1 )
+ {
+ e->accept();
+ ClickOnHelp();
+ }
+}
+
+
+//=================================================================================
+// function : onSelectMerge()
+// purpose :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::onSelectMerge(bool toMerge)
+{
+ TextLabelTol->setEnabled(toMerge);
+ SpinBoxTol->setEnabled(toMerge);
+
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_BuildCompoundDlg.h
+// Author : Alexander KOVALEV
+// Module : SMESH
+
+#ifndef SMESHGUI_BuildCompoundDlg_H
+#define SMESHGUI_BuildCompoundDlg_H
+
+#include "LightApp_SelectionMgr.h"
+#include "SUIT_SelectionFilter.h"
+
+// QT Includes
+#include <qdialog.h>
+
+#include <vector>
+
+// Open CASCADE Includes
+
+class QGridLayout;
+class QButtonGroup;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class SMESHGUI;
+class QCheckBox;
+class SMESHGUI_SpinBox;
+class QComboBox;
+class QSizePolicy;
+class QString;
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+
+//=================================================================================
+// class : SMESHGUI_BuildCompoundDlg
+// purpose :
+//=================================================================================
+class SMESHGUI_BuildCompoundDlg : public QDialog
+{
+ Q_OBJECT;
+
+ public:
+
+ SMESHGUI_BuildCompoundDlg (SMESHGUI * theModule);
+ ~SMESHGUI_BuildCompoundDlg();
+
+public :
+ static QString GetDefaultName(const QString& theOperation);
+
+ private:
+ void Init();
+ void closeEvent (QCloseEvent*);
+ void enterEvent (QEvent*); /* mouse enter the QWidget */
+ void hideEvent (QHideEvent*); /* ESC key */
+ void keyPressEvent(QKeyEvent*);
+
+ private:
+ SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
+ LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
+
+ SMESH::SMESH_Mesh_var myMesh;
+ SUIT_SelectionFilter* myMeshFilter;
+ SMESH::mesh_array_var myMeshArray;
+
+ // Widgets
+ QButtonGroup* GroupConstructors;
+ QRadioButton* Constructor1;
+
+ QGroupBox* GroupButtons;
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+ QPushButton* buttonApply;
+ QPushButton* buttonHelp;
+
+ QGroupBox* GroupName;
+ QLabel* TextLabelName;
+ QLineEdit* LineEditName;
+
+ QGroupBox* GroupArgs;
+ QLabel* TextLabelMeshes;
+ QPushButton* SelectButton;
+ QLineEdit* LineEditMeshes;
+ QLabel* TextLabelUnion;
+ QComboBox* ComboBoxUnion;
+ QCheckBox* CheckBoxMerge;
+ QLabel* TextLabelTol;
+ SMESHGUI_SpinBox* SpinBoxTol;
+
+ //protected:
+ QGridLayout* SMESHGUI_BuildCompoundDlgLayout;
+ QGridLayout* GroupConstructorsLayout;
+ QGridLayout* GroupButtonsLayout;
+ QGridLayout* GroupNameLayout;
+ QGridLayout* GroupArgsLayout;
+
+ QString myHelpFileName;
+
+ private slots:
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void ClickOnHelp();
+ void SelectionIntoArgument();
+ void DeactivateActiveDialog();
+ void ActivateThisDialog();
+ void onSelectMerge(bool);
+};
+
+#endif // SMESHGUI_BuildCompoundDlg_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_ComputeDlg.cxx
+// Author : Edward AGAPOV
+// Module : SMESH
+
+#include "SMESHGUI_ComputeDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+
+#include "SMDS_SetIterator.hxx"
+
+#include "GEOMBase.h"
+#include "GEOM_Actor.h"
+
+#include "LightApp_SelectionMgr.h"
+#include "LightApp_UpdateFlags.h"
+#include "SALOMEDSClient_SObject.hxx"
+#include "SALOME_ListIO.hxx"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_ViewModel.h"
+#include "SalomeApp_Tools.h"
+#include "SalomeApp_Application.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_Study.h"
+#include "OB_Browser.h"
+
+// OCCT Includes
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+
+#include <TopLoc_Location.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+
+// QT Includes
+#include <qframe.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qtable.h>
+#include <qhbox.h>
+#include <qhgroupbox.h>
+
+#include <vtkProperty.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+#include <vector>
+#include <set>
+
+
+#define SPACING 5
+#define MARGIN 10
+
+#define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
+
+#define _SEPARATOR(father) \
+{\
+ /*new QLabel(father); new QLabel(father); new QLabel(father)*/;\
+ (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+ (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+ (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+ (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+}
+
+enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, NB_COLUMNS };
+
+using namespace SMESH;
+
+namespace SMESH {
+
+ // =========================================================================================
+ /*!
+ * \brief Class showing shapes without publishing
+ */
+ // =========================================================================================
+
+ class TShapeDisplayer
+ {
+ public:
+ // -----------------------------------------------------------------------
+ TShapeDisplayer(): myViewWindow(0)
+ {
+ myProperty = vtkProperty::New();
+ myProperty->SetRepresentationToWireframe();
+ myProperty->SetColor( 250, 0, 250 );
+ myProperty->SetAmbientColor( 250, 0, 250 );
+ myProperty->SetDiffuseColor( 250, 0, 250 );
+ //myProperty->SetSpecularColor( 250, 0, 250 );
+ myProperty->SetLineWidth( 5 );
+ }
+ // -----------------------------------------------------------------------
+ ~TShapeDisplayer()
+ {
+ DeleteActors();
+ myProperty->Delete();
+ }
+ // -----------------------------------------------------------------------
+ void DeleteActors()
+ {
+ if ( hasViewWindow() ) {
+ TActorIterator actorIt = actorIterator();
+ while ( actorIt.more() )
+ if (VTKViewer_Actor* anActor = actorIt.next()) {
+ myViewWindow->RemoveActor( anActor );
+ //anActor->Delete();
+ }
+ }
+ myIndexToShape.Clear();
+ myActors.clear();
+ myShownActors.clear();
+ myBuiltSubs.clear();
+ }
+ // -----------------------------------------------------------------------
+ void SetVisibility (bool theVisibility)
+ {
+ TActorIterator actorIt = shownIterator();
+ while ( actorIt.more() )
+ if (VTKViewer_Actor* anActor = actorIt.next())
+ anActor->SetVisibility(theVisibility);
+ SMESH::RepaintCurrentView();
+ }
+ // -----------------------------------------------------------------------
+ bool HasReadyActorsFor (int subShapeID, GEOM::GEOM_Object_var aMainShape )
+ {
+ string mainEntry;
+ if ( !aMainShape->_is_nil() )
+ mainEntry = aMainShape->GetStudyEntry();
+ return ( myMainEntry == mainEntry &&
+ myBuiltSubs.find( subShapeID ) != myBuiltSubs.end() );
+ }
+ // -----------------------------------------------------------------------
+ void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false)
+ {
+ SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() );
+ string mainEntry;
+ if ( !aMainShape->_is_nil() )
+ mainEntry = aMainShape->GetStudyEntry();
+ if ( myMainEntry != mainEntry || aViewWindow != myViewWindow ) { // remove actors
+ DeleteActors();
+ TopoDS_Shape aShape;
+ if ( !aMainShape->_is_nil() && GEOMBase::GetShape(aMainShape, aShape)) {
+ checkTriangulation( aShape );
+ TopExp::MapShapes(aShape, myIndexToShape);
+ myActors.resize( myIndexToShape.Extent(), 0 );
+ myShownActors.reserve( myIndexToShape.Extent() );
+ }
+ myMainEntry = mainEntry;
+ myViewWindow = aViewWindow;
+ }
+ if ( only ) { // hide shown actors
+ TActorIterator actorIt = shownIterator();
+ while ( actorIt.more() )
+ if (VTKViewer_Actor* anActor = actorIt.next())
+ anActor->SetVisibility(false);
+ myShownActors.clear();
+ }
+ // find actors to show
+ TopoDS_Shape aShape = myIndexToShape( subShapeID );
+ if ( !aShape.IsNull() ) {
+ TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE );
+ for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) {
+ //checkTriangulation( exp.Current() );
+ if ( GEOM_Actor* anActor = getActor( exp.Current() ))
+ myShownActors.push_back( anActor );
+ }
+ if ( type == TopAbs_FACE ) {
+ for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+ const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() );
+ if ( !BRep_Tool::Degenerated( edge ))
+ if ( GEOM_Actor* anActor = getActor( exp.Current() ))
+ myShownActors.push_back( anActor );
+ }
+ }
+ }
+ myBuiltSubs.insert( subShapeID );
+ SetVisibility(true);
+ }
+ // -----------------------------------------------------------------------
+
+ private:
+
+ typedef std::vector<GEOM_Actor*> TActorVec;
+ TActorVec myActors;
+ TActorVec myShownActors;
+ TopTools_IndexedMapOfShape myIndexToShape;
+ string myMainEntry;
+ SVTK_ViewWindow* myViewWindow;
+ vtkProperty* myProperty;
+ std::set<int> myBuiltSubs;
+
+ // -----------------------------------------------------------------------
+ typedef SMDS_SetIterator< GEOM_Actor*, TActorVec::const_iterator> TActorIterator;
+ TActorIterator actorIterator() {
+ return TActorIterator( myActors.begin(), myActors.end() );
+ }
+ TActorIterator shownIterator() {
+ return TActorIterator( myShownActors.begin(), myShownActors.end() );
+ }
+ // -----------------------------------------------------------------------
+ GEOM_Actor* getActor(const TopoDS_Shape& shape)
+ {
+ int index = myIndexToShape.FindIndex( shape ) - 1;
+ if ( index < 0 || index >= myActors.size() )
+ return 0;
+ GEOM_Actor* & actor = myActors[ index ];
+ if ( !actor ) {
+ actor = GEOM_Actor::New();
+ if ( actor ) {
+ actor->setInputShape(shape,0,0);
+ //actor->SetProperty(myProperty);
+ actor->SetShadingProperty(myProperty);
+ actor->SetWireframeProperty(myProperty);
+ actor->SetPreviewProperty(myProperty);
+ actor->PickableOff();
+ // if ( shape.ShapeType() == TopAbs_EDGE )
+ // actor->SubShapeOn();
+ myViewWindow->AddActor( actor );
+ }
+ }
+ return actor;
+ }
+ // -----------------------------------------------------------------------
+ void checkTriangulation(const TopoDS_Shape& shape)
+ {
+ TopLoc_Location aLoc;
+ Standard_Boolean alreadymesh = Standard_True;
+ TopExp_Explorer ex(shape, TopAbs_FACE);
+ if ( ex.More() )
+ for (; ex.More(); ex.Next()) {
+ const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
+ Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
+ if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
+ }
+ else
+ for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) {
+ const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
+ Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(edge, aLoc);
+ if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
+ }
+ if (alreadymesh) return;
+ // Compute default deflection
+ Bnd_Box B;
+ BRepBndLib::Add(shape, B);
+ Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+ B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+ double deflection = Max( aXmax-aXmin , Max ( aYmax-aYmin , aZmax-aZmin)) * 0.01 *4;
+ BRepMesh_IncrementalMesh MESH(shape,deflection);
+ }
+ // -----------------------------------------------------------------------
+ bool hasViewWindow() const
+ {
+ if ( !myViewWindow ) return false;
+
+ if ( SalomeApp_Application* anApp = SMESHGUI::GetSMESHGUI()->getApp() )
+ return FindVtkViewWindow( anApp->getViewManager(SVTK_Viewer::Type(), false ),
+ myViewWindow );
+ return false;
+ }
+ };
+
+ // =========================================================================================
+ /*!
+ * \brief Return text describing an error
+ */
+#define CASE2TEXT(enum) case SMESH::enum: text = QObject::tr( #enum ); break;
+ QString errorText(int errCode, const char* comment)
+ {
+ QString text;
+ switch ( errCode ) {
+ CASE2TEXT( COMPERR_OK );
+ CASE2TEXT( COMPERR_BAD_INPUT_MESH);
+ CASE2TEXT( COMPERR_STD_EXCEPTION );
+ CASE2TEXT( COMPERR_OCC_EXCEPTION );
+ CASE2TEXT( COMPERR_SLM_EXCEPTION );
+ CASE2TEXT( COMPERR_EXCEPTION );
+ CASE2TEXT( COMPERR_MEMORY_PB );
+ CASE2TEXT( COMPERR_BAD_SHAPE );
+ case SMESH::COMPERR_ALGO_FAILED:
+ if ( strlen(comment) == 0 )
+ text = QObject::tr("COMPERR_ALGO_FAILED");
+ break;
+ default:
+ text = QString("#%1").arg( -errCode );
+ }
+ if ( text.length() > 0 ) text += ". ";
+ return text + comment;
+ }
+ // -----------------------------------------------------------------------
+ /*!
+ * \brief Return SO of a subshape
+ */
+ _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
+ {
+ _PTR(SObject) so = SMESH::FindSObject(aMainShape);
+ if ( subShapeID == 1 || !so )
+ return so;
+ _PTR(ChildIterator) it;
+ if (_PTR(Study) study = SMESH::GetActiveStudyDocument())
+ it = study->NewChildIterator(so);
+ _PTR(SObject) subSO;
+ if ( it ) {
+ for ( it->InitEx(true); !subSO && it->More(); it->Next() ) {
+ GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( it->Value() );
+ if ( !geom->_is_nil() ) {
+ GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+ if ( list->length() == 1 && list[0] == subShapeID )
+ subSO = it->Value();
+ }
+ }
+ }
+ return subSO;
+ }
+ // -----------------------------------------------------------------------
+ /*!
+ * \brief Return subshape by ID
+ */
+ GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
+ {
+ GEOM::GEOM_Object_var aSubShape;
+ if ( subShapeID == 1 )
+ aSubShape = aMainShape;
+ else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape ))
+ aSubShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>( so );
+ else
+ aSubShape = SMESH::GetSubShape( aMainShape, subShapeID );
+ return aSubShape._retn();
+ }
+ // -----------------------------------------------------------------------
+ /*!
+ * \brief Return shape type name
+ */
+#define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break;
+ QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" )
+ {
+ QString name = dflt;
+ if ( !aShape->_is_nil() ) {
+ switch ( aShape->GetShapeType() ) {
+ CASE2NAME( VERTEX );
+ CASE2NAME( EDGE );
+ CASE2NAME( WIRE );
+ CASE2NAME( FACE );
+ CASE2NAME( SHELL );
+ CASE2NAME( SOLID );
+ CASE2NAME( COMPSOLID );
+ CASE2NAME( COMPOUND );
+ default:;
+ }
+ }
+ return name;
+ }
+ // -----------------------------------------------------------------------
+ /*!
+ * \brief Return text describing a subshape
+ */
+ QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
+ {
+ QString text;
+ if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
+ text = aSO->GetName();
+ else {
+ text = QString("#%1").arg( subShapeID );
+ QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape ));
+ if ( typeName.length() )
+ text += QString(" (%1)").arg(typeName);
+ }
+ return text;
+ }
+ // -----------------------------------------------------------------------
+ /*!
+ * \brief Return text describing a subshape
+ */
+ bool getSelectedRows(QTable* table, list< int > & rows)
+ {
+ rows.clear();
+ int nbSel = table->numSelections();
+ for ( int i = 0; i < nbSel; ++i )
+ {
+ QTableSelection selected = table->selection(i);
+ if ( !selected.isActive() ) continue;
+ for ( int row = selected.topRow(); row <= selected.bottomRow(); ++row )
+ rows.push_back( row );
+ }
+ return !rows.empty();
+ }
+
+} // namespace SMESH
+
+
+// =========================================================================================
+/*!
+ * \brief Box showing mesh info
+ */
+// =========================================================================================
+
+SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent)
+ :QGroupBox( 4, Qt::Horizontal, tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full )
+{
+ // title
+ QLabel* lab1 = new QLabel(this);
+ QLabel* lab2 = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this );
+ QLabel* lab3 = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this );
+ QLabel* lab4 = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this );
+
+ QFont italic = lab1->font(); italic.setItalic(true);
+ QFont bold = lab1->font(); bold.setBold(true);
+
+ lab1->setMinimumWidth(100); lab1->setFont( italic );
+ lab2->setMinimumWidth(100); lab2->setFont( italic );
+ lab3->setMinimumWidth(100); lab3->setFont( italic );
+ lab4->setMinimumWidth(100); lab4->setFont( italic );
+
+ if ( myFull )
+ {
+ // nodes
+ (new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ))->setFont( bold );
+ myNbNode = new QLabel( this );
+ new QLabel(this);
+ new QLabel(this);
+
+ _SEPARATOR(this);
+
+ // edges
+ (new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ))->setFont( bold );
+ myNbEdge = new QLabel( this );
+ myNbLinEdge = new QLabel( this );
+ myNbQuadEdge = new QLabel( this );
+
+ _SEPARATOR(this);
+
+ // faces
+ (new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this))->setFont( bold );
+ myNbFace = new QLabel( this );
+ myNbLinFace = new QLabel( this );
+ myNbQuadFace = new QLabel( this );
+ // triangles
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this );
+ myNbTrai = new QLabel( this );
+ myNbLinTrai = new QLabel( this );
+ myNbQuadTrai = new QLabel( this );
+ // quadrangles
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this );
+ myNbQuad = new QLabel( this );
+ myNbLinQuad = new QLabel( this );
+ myNbQuadQuad = new QLabel( this );
+ // poligones
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
+ myNbPolyg = new QLabel( this );
+ new QLabel("",this );
+ new QLabel("", this );
+
+ _SEPARATOR(this);
+
+ // volumes
+ (new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this))->setFont( bold );
+ myNbVolum = new QLabel( this );
+ myNbLinVolum = new QLabel( this );
+ myNbQuadVolum = new QLabel( this );
+ // tetras
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this );
+ myNbTetra = new QLabel( this );
+ myNbLinTetra = new QLabel( this );
+ myNbQuadTetra = new QLabel( this );
+ // hexas
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this );
+ myNbHexa = new QLabel( this );
+ myNbLinHexa = new QLabel( this );
+ myNbQuadHexa = new QLabel( this );
+ // pyras
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this );
+ myNbPyra = new QLabel( this );
+ myNbLinPyra = new QLabel( this );
+ myNbQuadPyra = new QLabel( this );
+ // prisms
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this );
+ myNbPrism = new QLabel( this );
+ myNbLinPrism = new QLabel( this );
+ myNbQuadPrism = new QLabel( this );
+ // polyedres
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this );
+ myNbPolyh = new QLabel( this );
+ new QLabel("", this );
+ new QLabel("", this );
+ }
+ else
+ {
+ // nodes
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
+ myNbNode = new QLabel( this );
+ new QLabel(this);
+ new QLabel(this);
+
+ // edges
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
+ myNbEdge = new QLabel( this );
+ myNbLinEdge = new QLabel( this );
+ myNbQuadEdge = new QLabel( this );
+
+ // faces
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
+ myNbFace = new QLabel( this );
+ myNbLinFace = new QLabel( this );
+ myNbQuadFace = new QLabel( this );
+
+ // volumes
+ new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
+ myNbVolum = new QLabel( this );
+ myNbLinVolum = new QLabel( this );
+ myNbQuadVolum = new QLabel( this );
+ }
+}
+
+// =========================================================================================
+/*!
+ * \brief Set mesh info
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
+{
+ const SMESH::ElementOrder lin = SMESH::ORDER_LINEAR;
+ int nbTot, nbLin;
+
+ // nodes
+ myNbNode ->setText( QString("%1").arg( mesh->NbNodes() ));
+
+ // edges
+ nbTot = mesh->NbEdges(), nbLin = mesh->NbEdgesOfOrder(lin);
+ myNbEdge ->setText( QString("%1").arg( nbTot ));
+ myNbLinEdge ->setText( QString("%1").arg( nbLin ));
+ myNbQuadEdge ->setText( QString("%1").arg( nbTot - nbLin ));
+
+ // faces
+ nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin);
+ myNbFace ->setText( QString("%1").arg( nbTot ));
+ myNbLinFace ->setText( QString("%1").arg( nbLin ));
+ myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin ));
+
+ // volumes
+ nbTot = mesh->NbVolumes(), nbLin = mesh->NbVolumesOfOrder(lin);
+ myNbVolum ->setText( QString("%1").arg( nbTot ));
+ myNbLinVolum ->setText( QString("%1").arg( nbLin ));
+ myNbQuadVolum->setText( QString("%1").arg( nbTot - nbLin ));
+
+ if ( myFull )
+ {
+ // triangles
+ nbTot = mesh->NbTriangles(), nbLin = mesh->NbTrianglesOfOrder(lin);
+ myNbTrai ->setText( QString("%1").arg( nbTot ));
+ myNbLinTrai ->setText( QString("%1").arg( nbLin ));
+ myNbQuadTrai ->setText( QString("%1").arg( nbTot - nbLin ));
+ // quadrangles
+ nbTot = mesh->NbQuadrangles(), nbLin = mesh->NbQuadranglesOfOrder(lin);
+ myNbQuad ->setText( QString("%1").arg( nbTot ));
+ myNbLinQuad ->setText( QString("%1").arg( nbLin ));
+ myNbQuadQuad ->setText( QString("%1").arg( nbTot - nbLin ));
+ // poligones
+ myNbPolyg ->setText( QString("%1").arg( mesh->NbPolygons() ));
+
+ // tetras
+ nbTot = mesh->NbTetras(), nbLin = mesh->NbTetrasOfOrder(lin);
+ myNbTetra ->setText( QString("%1").arg( nbTot ));
+ myNbLinTetra ->setText( QString("%1").arg( nbLin ));
+ myNbQuadTetra->setText( QString("%1").arg( nbTot - nbLin ));
+ // hexas
+ nbTot = mesh->NbHexas(), nbLin = mesh->NbHexasOfOrder(lin);
+ myNbHexa ->setText( QString("%1").arg( nbTot ));
+ myNbLinHexa ->setText( QString("%1").arg( nbLin ));
+ myNbQuadHexa ->setText( QString("%1").arg( nbTot - nbLin ));
+ // pyras
+ nbTot = mesh->NbPyramids(), nbLin = mesh->NbPyramidsOfOrder(lin);
+ myNbPyra ->setText( QString("%1").arg( nbTot ));
+ myNbLinPyra ->setText( QString("%1").arg( nbLin ));
+ myNbQuadPyra ->setText( QString("%1").arg( nbTot - nbLin ));
+ // prisms
+ nbTot = mesh->NbPrisms(), nbLin = mesh->NbPrismsOfOrder(lin);
+ myNbPrism ->setText( QString("%1").arg( nbTot ));
+ myNbLinPrism ->setText( QString("%1").arg( nbLin ));
+ myNbQuadPrism->setText( QString("%1").arg( nbTot - nbLin ));
+ // polyedres
+ myNbPolyh ->setText( QString("%1").arg( mesh->NbPolyhedrons() ));
+ }
+}
+
+// =========================================================================================
+/*!
+ * \brief Dialog to compute a mesh and show computation errors
+ */
+//=======================================================================
+
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, OK/* | Help*/ )
+{
+ QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), 0, SPACING);
+
+ QFrame* aMainFrame = createMainFrame (mainFrame());
+
+ aDlgLay->addWidget(aMainFrame);
+
+ aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//=======================================================================
+// function : createMainFrame()
+// purpose : Create frame containing dialog's fields
+//=======================================================================
+
+#define CASE2HEADER(enum) case enum: header = QObject::tr( #enum "_HEADER" ); break;
+
+QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
+{
+ QFrame* aFrame = new QFrame(theParent);
+
+ SUIT_ResourceMgr* rm = resourceMgr();
+ QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE")));
+
+ // constructor
+
+ QButtonGroup* aPixGrp = new QButtonGroup(1, Qt::Vertical, tr("CONSTRUCTOR"), aFrame);
+ aPixGrp->setExclusive(TRUE);
+ QRadioButton* aRBut = new QRadioButton(aPixGrp);
+ aRBut->setPixmap(iconCompute);
+ aRBut->setChecked(TRUE);
+
+ // Mesh name
+
+ QHGroupBox* nameBox = new QHGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
+ myMeshName = new QLabel(nameBox);
+
+ // Mesh Info
+
+ myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame);
+ myFullInfo = new SMESHGUI_MeshInfosBox(true, aFrame);
+
+ // errors
+
+ myErrorGroup = new QGroupBox(tr("ERRORS"), aFrame, "errorGrBox");
+ myTable = new QTable( 1, NB_COLUMNS, myErrorGroup, "myTable");
+ myShowBtn = new QPushButton(tr("SHOW_SHAPE"), myErrorGroup, "myShowBtn");
+ myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myErrorGroup, "myPublishBtn");
+
+ myTable->setReadOnly( TRUE );
+ myTable->hideColumn( COL_PUBLISHED );
+ myTable->hideColumn( COL_SHAPEID );
+ myTable->setColumnStretchable( COL_ERROR, 1 );
+ for ( int col = 0; col < NB_COLUMNS; ++col ) {
+ QString header;
+ switch ( col ) {
+ CASE2HEADER( COL_ALGO );
+ CASE2HEADER( COL_SHAPE );
+ CASE2HEADER( COL_ERROR );
+ CASE2HEADER( COL_SHAPEID );
+ CASE2HEADER( COL_PUBLISHED);
+ }
+ myTable->horizontalHeader()->setLabel( col, header );
+ }
+
+ myErrorGroup->setColumnLayout(0, Qt::Vertical);
+ myErrorGroup->layout()->setSpacing(0);
+ myErrorGroup->layout()->setMargin(0);
+ QGridLayout* grpLayout = new QGridLayout(myErrorGroup->layout());
+ grpLayout->setAlignment(Qt::AlignTop);
+ grpLayout->setSpacing(SPACING);
+ grpLayout->setMargin(MARGIN);
+ grpLayout->addMultiCellWidget( myTable, 0, 2, 0, 0 );
+ grpLayout->addWidget ( myShowBtn, 0, 1 );
+ grpLayout->addWidget ( myPublishBtn, 1, 1 );
+ grpLayout->setRowStretch( 2, 1 );
+
+ QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+ aLay->addWidget( aPixGrp );
+ aLay->addWidget( nameBox );
+ aLay->addWidget( myBriefInfo );
+ aLay->addWidget( myFullInfo );
+ aLay->addWidget( myErrorGroup );
+ aLay->setStretchFactor( myErrorGroup, 1 );
+
+ return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
+{
+ myDlg = new SMESHGUI_ComputeDlg;
+ myTShapeDisplayer = new TShapeDisplayer();
+ myHelpFileName = "/files/about_meshes.htm";
+
+ // connect signals and slots
+ connect(myDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape()));
+ connect(myDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+ connect(table(),SIGNAL(selectionChanged()), SLOT(currentCellChanged()));
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+
+void SMESHGUI_ComputeOp::startOperation()
+{
+ SMESHGUI_Operation::startOperation();
+
+ SMESH::SMESH_Mesh_var aMesh;
+ SMESH::compute_error_array_var anErrors;
+
+ myMainShape = GEOM::GEOM_Object::_nil();
+
+ // COMPUTE MESH
+
+ bool computeFailed = true;
+ int nbNodes = 0, nbEdges = 0, nbFaces = 0, nbVolums = 0;
+
+ LightApp_SelectionMgr *Sel = selectionMgr();
+ SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+ int nbSel = selected.Extent();
+ if (nbSel != 1) {
+ SUIT_MessageBox::warn1(desktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_NO_AVAILABLE_DATA"),
+ tr("SMESH_BUT_OK"));
+ onCancel();
+ return;
+ }
+
+ Handle(SALOME_InteractiveObject) IObject = selected.First();
+ aMesh = SMESH::GetMeshByIO(IObject);
+ if (!aMesh->_is_nil()) {
+ myMainShape = aMesh->GetShapeToMesh();
+ if ( !myMainShape->_is_nil() ) {
+ SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+ SMESH::algo_error_array_var errors = gen->GetAlgoState(aMesh,myMainShape);
+ if ( errors->length() > 0 ) {
+ SUIT_MessageBox::warn1(desktop(), tr("SMESH_WRN_WARNING"),
+ SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
+ tr("SMESH_BUT_OK"));
+ onCancel();
+ return;
+ }
+ try {
+ if (gen->Compute(aMesh, myMainShape)) {
+ computeFailed = false;
+ }
+ else {
+ anErrors = gen->GetComputeErrors( aMesh, myMainShape );
+// if ( anErrors->length() == 0 ) {
+// SUIT_MessageBox::warn1(desktop(),
+// tr("SMESH_WRN_WARNING"),
+// tr("SMESH_WRN_COMPUTE_FAILED"),
+// tr("SMESH_BUT_OK"));
+// onCancel();
+// return;
+// }
+ }
+ if ( _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh)) {
+ SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0);
+ myDlg->myMeshName->setText( aMeshSObj->GetName() );
+ }
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ SalomeApp_Tools::QtCatchCorbaException(S_ex);
+ }
+ update( UF_ObjBrowser | UF_Model );
+
+ if ( getSMESHGUI()->automaticUpdate() ) {
+ SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(getSMESHGUI(), true);
+ if (aVTKView) {
+ int anId = study()->id();
+ TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry());
+ if (aVisualObj) {
+ aVisualObj->Update();
+ SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
+ if (!anActor) {
+ anActor = SMESH::CreateActor(studyDS(), IObject->getEntry());
+ if (anActor) {
+ SMESH::DisplayActor(aVTKView, anActor); //apo
+ SMESH::FitAll();
+ }
+ }
+ SMESH::RepaintCurrentView();
+ Sel->setSelectedObjects( selected );
+ }
+ }
+ }
+ }
+ }
+
+ myDlg->setCaption(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+
+ // SHOW ERRORS
+
+ bool noError = ( !anErrors.operator->() || anErrors->length() == 0 );
+
+ QTable* tbl = myDlg->myTable;
+
+ if ( noError )
+ {
+ //tbl->setNumRows(0);
+ myDlg->myFullInfo->SetInfoByMesh( aMesh );
+ myDlg->myFullInfo->show();
+ myDlg->myBriefInfo->hide();
+ myDlg->myErrorGroup->hide();
+ }
+ else
+ {
+ myDlg->myBriefInfo->SetInfoByMesh( aMesh );
+ myDlg->myBriefInfo->show();
+ myDlg->myFullInfo->hide();
+ myDlg->myErrorGroup->show();
+
+ // fill table of errors
+ tbl->setNumRows( anErrors->length() );
+ bool hasShape = aMesh->HasShapeToMesh();
+ if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+ else tbl->showColumn( COL_SHAPE );
+ tbl->setColumnWidth( COL_ERROR, 200 );
+
+ for ( int row = 0; row < anErrors->length(); ++row )
+ {
+ SMESH::ComputeError & err = anErrors[ row ];
+ tbl->setText( row, COL_ALGO, err.algoName.in() );
+ tbl->setText( row, COL_ERROR, errorText( err.code, err.comment.in() ));
+ tbl->setText( row, COL_SHAPEID, QString("%1").arg( err.subShapeID ));
+
+ QString text = hasShape ? shapeText( err.subShapeID, myMainShape ) : QString("");
+ tbl->setText( row, COL_SHAPE, text );
+
+ text = ( !hasShape || getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+ tbl->setText( row, COL_PUBLISHED, text ); // if text=="", "PUBLISH" button enabled
+
+ tbl->item( row, COL_ERROR )->setWordWrap( TRUE );
+ tbl->adjustRow( row );
+ }
+ tbl->adjustColumn( COL_ALGO );
+ tbl->adjustColumn( COL_SHAPE );
+
+ tbl->setCurrentCell(0,0);
+ currentCellChanged(); // to update buttons
+ }
+
+ myDlg->show();
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::stopOperation()
+{
+ SMESHGUI_Operation::stopOperation();
+ myTShapeDisplayer->SetVisibility( false );
+}
+
+//================================================================================
+/*!
+ * \brief publish selected subshape
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::onPublishShape()
+{
+ GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+ SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
+
+ list< int > rows;
+ list< int >::iterator row;
+ getSelectedRows( table(), rows );
+ for ( row = rows.begin(); row != rows.end(); ++row )
+ {
+ int curSub = table()->text(*row, COL_SHAPEID).toInt();
+ GEOM::GEOM_Object_var shape = getSubShape( curSub, myMainShape );
+ if ( !shape->_is_nil() && ! getSubShapeSO( curSub, myMainShape ))
+ {
+ if ( !getSubShapeSO( 1, myMainShape )) // the main shape not published
+ {
+ QString name = GEOMBase::GetDefaultName( shapeTypeName( myMainShape, "MAIN_SHAPE" ));
+ SALOMEDS::SObject_var so =
+ geomGen->AddInStudy( study, myMainShape, name, GEOM::GEOM_Object::_nil());
+ // look for myMainShape in the table
+ for ( int r = 0, nr = table()->numRows(); r < nr; ++r ) {
+ if ( table()->text(r, COL_SHAPEID) == "1" ) {
+ if ( so->_is_nil() ) {
+ table()->setText( r, COL_SHAPE, so->GetName() );
+ table()->setText( r, COL_PUBLISHED, so->GetID() );
+ }
+ break;
+ }
+ }
+ if ( curSub == 1 ) continue;
+ }
+ QString name = GEOMBase::GetDefaultName( shapeTypeName( shape, "ERROR_SHAPE" ));
+ SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name, myMainShape);
+ if ( !so->_is_nil() ) {
+ table()->setText( *row, COL_SHAPE, so->GetName() );
+ table()->setText( *row, COL_PUBLISHED, so->GetID() );
+ }
+ }
+ }
+ getSMESHGUI()->getApp()->updateObjectBrowser();
+ currentCellChanged(); // to update buttons
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when a selected cell in table() changed
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::currentCellChanged()
+{
+ myTShapeDisplayer->SetVisibility( false );
+
+ bool publishEnable = 0, showEnable = 0, showOnly = 1;
+ list< int > rows;
+ list< int >::iterator row;
+ getSelectedRows( table(), rows );
+ for ( row = rows.begin(); row != rows.end(); ++row )
+ {
+ bool hasData = ( !table()->text(*row, COL_SHAPE).isEmpty() );
+ bool isPublished = ( !table()->text(*row, COL_PUBLISHED).isEmpty() );
+ if ( hasData && !isPublished )
+ publishEnable = true;
+
+ int curSub = table()->text(*row, COL_SHAPEID).toInt();
+ bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
+ if ( prsReady ) {
+ myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
+ showOnly = false;
+ }
+ else {
+ showEnable = true;
+ }
+ }
+ myDlg->myPublishBtn->setEnabled( publishEnable );
+ myDlg->myShowBtn->setEnabled( showEnable );
+}
+
+//================================================================================
+/*!
+ * \brief update preview
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::onPreviewShape()
+{
+ if ( myTShapeDisplayer )
+ {
+ SUIT_OverrideCursor aWaitCursor;
+ list< int > rows;
+ list< int >::iterator row;
+ getSelectedRows( table(), rows );
+
+ bool showOnly = true;
+ for ( row = rows.begin(); row != rows.end(); ++row )
+ {
+ int curSub = table()->text(*row, COL_SHAPEID).toInt();
+ if ( curSub > 0 ) {
+ myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
+ showOnly = false;
+ }
+ }
+ currentCellChanged(); // to update buttons
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
+{
+ if ( myTShapeDisplayer ) delete myTShapeDisplayer;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
+{
+ return myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+bool SMESHGUI_ComputeOp::onApply()
+{
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return a table
+ */
+//================================================================================
+
+QTable* SMESHGUI_ComputeOp::table()
+{
+ return myDlg->myTable;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_ComputeDlg.h
+// Author : Edward AGAPOV
+// Module : SMESH
+
+
+#ifndef SMESHGUI_ComputeDlg_H
+#define SMESHGUI_ComputeDlg_H
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+#include "VTKViewer.h"
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+
+#include <qgroupbox.h>
+
+class QFrame;
+class QPushButton;
+class QTable;
+class QLabel;
+class SMESHGUI_ComputeDlg;
+class GEOM_Actor;
+
+namespace SMESH {
+ class TShapeDisplayer;
+}
+
+/*!
+ * \brief Operation to compute a mesh and show computation errors
+ */
+class SMESHGUI_ComputeOp: public SMESHGUI_Operation
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_ComputeOp();
+ virtual ~SMESHGUI_ComputeOp();
+
+ virtual LightApp_Dialog* dlg() const;
+
+protected:
+
+ virtual void startOperation();
+ virtual void stopOperation();
+
+protected slots:
+ virtual bool onApply();
+
+private slots:
+
+ void onPreviewShape();
+ void onPublishShape();
+ void currentCellChanged();
+
+private:
+
+ QTable* table();
+
+ SMESHGUI_ComputeDlg* myDlg;
+
+ GEOM::GEOM_Object_var myMainShape;
+ SMESH::TShapeDisplayer* myTShapeDisplayer;
+};
+
+/*!
+ * \brief Box showing mesh info
+ */
+
+class SMESHGUI_MeshInfosBox : public QGroupBox
+{
+ Q_OBJECT
+public:
+
+ SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent);
+ void SetInfoByMesh(SMESH::SMESH_Mesh_var mesh);
+
+private:
+
+ bool myFull;
+ QLabel* myNbNode;
+ QLabel* myNbEdge, *myNbLinEdge, *myNbQuadEdge;
+ QLabel* myNbTrai, *myNbLinTrai, *myNbQuadTrai;
+ QLabel* myNbQuad, *myNbLinQuad, *myNbQuadQuad;
+ QLabel* myNbFace, *myNbLinFace, *myNbQuadFace;
+ QLabel* myNbPolyg;
+ QLabel* myNbHexa, *myNbLinHexa, *myNbQuadHexa;
+ QLabel* myNbTetra, *myNbLinTetra, *myNbQuadTetra;
+ QLabel* myNbPyra, *myNbLinPyra, *myNbQuadPyra;
+ QLabel* myNbPrism, *myNbLinPrism, *myNbQuadPrism;
+ QLabel* myNbVolum, *myNbLinVolum, *myNbQuadVolum;
+ QLabel* myNbPolyh;
+};
+
+/*!
+ * \brief Dialog to compute a mesh and show computation errors
+ */
+
+class SMESHGUI_ComputeDlg : public SMESHGUI_Dialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_ComputeDlg();
+
+private:
+
+ QFrame* createMainFrame (QWidget*);
+
+ QLabel* myMeshName;
+ QGroupBox* myErrorGroup;
+ QTable* myTable;
+ QPushButton* myShowBtn;
+ QPushButton* myPublishBtn;
+
+ SMESHGUI_MeshInfosBox* myBriefInfo;
+ SMESHGUI_MeshInfosBox* myFullInfo;
+
+ friend class SMESHGUI_ComputeOp;
+
+};
+
+#endif
#include "LightApp_UpdateFlags.h"
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
//================================================================================
/*!
* \brief Constructor
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
// name : resourceMgr
// Purpose : Gets resource manager
//=======================================================================
-SUIT_ResourceMgr* resourceMgr()
+SUIT_ResourceMgr* SMESHGUI_Dialog::resourceMgr()
{
return SUIT_Session::session()->resourceMgr();
}
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESH_Actor.h"
#include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMDS_Mesh.hxx"
-#include "SUIT_Desktop.h"
+#include "GEOMBase.h"
+
+#include "SUIT_ResourceMgr.h"
#include "SUIT_Session.h"
#include "SUIT_MessageBox.h"
#include "LightApp_Application.h"
+#include "SVTK_ViewModel.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_Selector.h"
+#include "SVTK_Selection.h"
#include "SALOME_ListIO.hxx"
#include "utilities.h"
+// OCCT Includes
+#include <gp_XYZ.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+//IDL Headers
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+// VTK Includes
+#include <vtkUnstructuredGrid.h>
+#include <vtkRenderer.h>
+#include <vtkActor2D.h>
+#include <vtkPoints.h>
+#include <vtkDataSetMapper.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkIntArray.h>
+#include <vtkPolyData.h>
+#include <vtkProperty2D.h>
+#include <vtkPointData.h>
+
// QT Includes
#include <qapplication.h>
#include <qbuttongroup.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlineedit.h>
+#include <qlistbox.h>
+#include <qlistview.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
+#include <qcheckbox.h>
#include <qlayout.h>
#include <qpixmap.h>
+#include <qheader.h>
+
+using namespace std;
+
+namespace SMESH {
+ class TIdPreview { // to display in the viewer IDs of the selected elements
+ SVTK_ViewWindow* myViewWindow;
+
+ vtkUnstructuredGrid* myIdGrid;
+ SALOME_Actor* myIdActor;
+
+ vtkUnstructuredGrid* myPointsNumDataSet;
+ vtkMaskPoints* myPtsMaskPoints;
+ vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+ vtkLabeledDataMapper* myPtsLabeledDataMapper;
+ vtkTextProperty* aPtsTextProp;
+ bool myIsPointsLabeled;
+ vtkActor2D* myPointLabels;
+
+ vector<int> myIDs;
+
+ public:
+ TIdPreview(SVTK_ViewWindow* theViewWindow):
+ myViewWindow(theViewWindow)
+ {
+ myIdGrid = vtkUnstructuredGrid::New();
+
+ // Create and display actor
+ vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+ aMapper->SetInput( myIdGrid );
+
+ myIdActor = SALOME_Actor::New();
+ myIdActor->SetInfinitive(true);
+ myIdActor->VisibilityOff();
+ myIdActor->PickableOff();
+
+ myIdActor->SetMapper( aMapper );
+ aMapper->Delete();
+
+ myViewWindow->AddActor(myIdActor);
+
+ //Definition of points numbering pipeline
+ myPointsNumDataSet = vtkUnstructuredGrid::New();
+
+ myPtsMaskPoints = vtkMaskPoints::New();
+ myPtsMaskPoints->SetInput(myPointsNumDataSet);
+ myPtsMaskPoints->SetOnRatio(1);
+
+ myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+ myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
+ myPtsSelectVisiblePoints->SelectInvisibleOff();
+ myPtsSelectVisiblePoints->SetTolerance(0.1);
+
+ myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+ myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
+ myPtsLabeledDataMapper->SetLabelFormat("%g");
+ myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+
+ vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+ aPtsTextProp->SetFontFamilyToTimes();
+ static int aPointsFontSize = 12;
+ aPtsTextProp->SetFontSize(aPointsFontSize);
+ aPtsTextProp->SetBold(1);
+ aPtsTextProp->SetItalic(0);
+ aPtsTextProp->SetShadow(0);
+ myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
+ aPtsTextProp->Delete();
+
+ myIsPointsLabeled = false;
+
+ myPointLabels = vtkActor2D::New();
+ myPointLabels->SetMapper(myPtsLabeledDataMapper);
+ myPointLabels->GetProperty()->SetColor(1,1,1);
+ myPointLabels->SetVisibility(myIsPointsLabeled);
+
+ AddToRender(myViewWindow->getRenderer());
+ }
+
+ void SetPointsData ( SMDS_Mesh* theMesh,
+ TColStd_MapOfInteger & theNodesIdMap )
+ {
+ vtkPoints* aPoints = vtkPoints::New();
+ aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
+ myIDs.clear();
+
+ TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
+ for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
+ const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
+ aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
+ myIDs.push_back(idIter.Key());
+ }
+
+ myIdGrid->SetPoints(aPoints);
+
+ aPoints->Delete();
+
+ myIdActor->GetMapper()->Update();
+ }
+
+ void SetElemsData( TColStd_MapOfInteger & theElemsIdMap,
+ list<gp_XYZ> & aGrCentersXYZ )
+ {
+ vtkPoints* aPoints = vtkPoints::New();
+ aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
+ myIDs.clear();
+
+ TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+ for( ; idIter.More(); idIter.Next() ) {
+ myIDs.push_back(idIter.Key());
+ }
+
+ gp_XYZ aXYZ;
+ list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
+ for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
+ aXYZ = *coordIt;
+ aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
+ }
+ myIdGrid->SetPoints(aPoints);
+ aPoints->Delete();
+
+ myIdActor->GetMapper()->Update();
+ }
+
+ void AddToRender(vtkRenderer* theRenderer)
+ {
+ myIdActor->AddToRender(theRenderer);
+
+ myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+ theRenderer->AddActor2D(myPointLabels);
+ }
+
+ void RemoveFromRender(vtkRenderer* theRenderer)
+ {
+ myIdActor->RemoveFromRender(theRenderer);
+
+ myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+ theRenderer->RemoveActor(myPointLabels);
+ }
+
+ void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
+ {
+ myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
+
+ if ( myIsPointsLabeled ) {
+ myPointsNumDataSet->ShallowCopy(myIdGrid);
+ vtkDataSet *aDataSet = myPointsNumDataSet;
+ int aNbElem = myIDs.size();
+ vtkIntArray *anArray = vtkIntArray::New();
+ anArray->SetNumberOfValues( aNbElem );
+ for ( int i = 0; i < aNbElem; i++ )
+ anArray->SetValue( i, myIDs[i] );
+ aDataSet->GetPointData()->SetScalars( anArray );
+ anArray->Delete();
+ myPtsMaskPoints->SetInput( aDataSet );
+ myPointLabels->SetVisibility( theIsActorVisible );
+ }
+ else {
+ myPointLabels->SetVisibility( false );
+ }
+ }
+
+ ~TIdPreview()
+ {
+ RemoveFromRender(myViewWindow->getRenderer());
+
+ myIdGrid->Delete();
+
+ myViewWindow->RemoveActor(myIdActor);
+ myIdActor->Delete();
+
+ //Deleting of points numbering pipeline
+ //---------------------------------------
+ myPointsNumDataSet->Delete();
+
+ myPtsLabeledDataMapper->RemoveAllInputs();
+ myPtsLabeledDataMapper->Delete();
+
+ myPtsSelectVisiblePoints->UnRegisterAllOutputs();
+ myPtsSelectVisiblePoints->Delete();
+
+ myPtsMaskPoints->UnRegisterAllOutputs();
+ myPtsMaskPoints->Delete();
+
+ myPointLabels->Delete();
+
+// myTimeStamp->Delete();
+ }
+ };
+}
+
+static const char * IconFirst[] = {
+"18 10 2 1",
+" g None",
+". g #000000",
+" . . ",
+" .. .. .. ",
+" .. ... ... ",
+" .. .... .... ",
+" .. ..... ..... ",
+" .. ..... ..... ",
+" .. .... .... ",
+" .. ... ... ",
+" .. .. .. ",
+" . . "};
//=================================================================================
// class : SMESHGUI_EditMeshDlg()
// purpose :
//=================================================================================
-SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
- const char* title, const char* icon,
- int theAction)
+SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
+ int theAction)
: QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_EditMeshDlg", false, WStyle_Customize |
WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
mySMESHGUI(theModule),
mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
myAction(theAction)
{
- resize(303, 185);
- setCaption(tr(title));
+ setCaption(tr("SMESH_MERGE_NODES"));
- SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
- QPixmap image0 (aResMgr->loadPixmap("SMESH", tr(icon)));
- QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+ myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
+
+ SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
+ QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
+ QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
+ QPixmap IconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+ QPixmap IconAdd (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
+ QPixmap IconRemove (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
setSizeGripEnabled(TRUE);
DlgLayout = new QGridLayout (this);
/***************************************************************/
GroupConstructors = new QButtonGroup (this, "GroupConstructors");
+ GroupConstructors->setTitle(tr("SMESH_MERGE_NODES"));
GroupConstructors->setExclusive(TRUE);
GroupConstructors->setColumnLayout(0, Qt::Vertical);
GroupConstructors->layout()->setSpacing(0);
GroupConstructors->layout()->setMargin(0);
- GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout());
+ GroupConstructorsLayout = new QGridLayout(GroupConstructors->layout());
GroupConstructorsLayout->setAlignment(Qt::AlignTop);
GroupConstructorsLayout->setSpacing(6);
GroupConstructorsLayout->setMargin(11);
- Constructor1 = new QRadioButton (GroupConstructors, "Constructor1");
- Constructor1->setText(tr(""));
- Constructor1->setPixmap(image0);
- Constructor1->setChecked(TRUE);
- Constructor1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1,
- (QSizePolicy::SizeType)0,
- Constructor1->sizePolicy().hasHeightForWidth()));
- Constructor1->setMinimumSize(QSize(50, 0));
- GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
- QSpacerItem* spacer = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- GroupConstructorsLayout->addItem(spacer, 0, 1);
+ RadioButton = new QRadioButton(GroupConstructors, "RadioButton");
+ RadioButton->setPixmap(IconMergeNodes);
+ if (myAction == 1) RadioButton->setPixmap(IconMergeElems);
+ RadioButton->setChecked(TRUE);
+ GroupConstructorsLayout->addWidget(RadioButton, 0, 0);
DlgLayout->addWidget(GroupConstructors, 0, 0);
/***************************************************************/
GroupButtons = new QGroupBox (this, "GroupButtons");
- GroupButtons->setGeometry(QRect(10, 10, 281, 48));
GroupButtons->setTitle(tr("" ));
GroupButtons->setColumnLayout(0, Qt::Vertical);
GroupButtons->layout()->setSpacing(0);
GroupButtons->layout()->setMargin(0);
- GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
+ GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
GroupButtonsLayout->setAlignment(Qt::AlignTop);
GroupButtonsLayout->setSpacing(6);
GroupButtonsLayout->setMargin(11);
buttonHelp->setText(tr("SMESH_BUT_HELP" ));
buttonHelp->setAutoDefault(TRUE);
GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
- buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
+ buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
buttonCancel->setAutoDefault(TRUE);
GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
- buttonApply = new QPushButton (GroupButtons, "buttonApply");
+ buttonApply = new QPushButton(GroupButtons, "buttonApply");
buttonApply->setText(tr("SMESH_BUT_APPLY" ));
buttonApply->setAutoDefault(TRUE);
GroupButtonsLayout->addWidget(buttonApply, 0, 1);
- QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- GroupButtonsLayout->addItem(spacer_9, 0, 2);
- buttonOk = new QPushButton (GroupButtons, "buttonOk");
+ QSpacerItem* spacer3 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ GroupButtonsLayout->addItem(spacer3, 0, 2);
+ buttonOk = new QPushButton(GroupButtons, "buttonOk");
buttonOk->setText(tr("SMESH_BUT_OK" ));
buttonOk->setAutoDefault(TRUE);
buttonOk->setDefault(TRUE);
GroupButtonsLayout->addWidget(buttonOk, 0, 0);
- DlgLayout->addWidget(GroupButtons, 2, 0);
+ DlgLayout->addWidget(GroupButtons, 4, 0);
/***************************************************************/
- GroupMesh = new QGroupBox (this, "GroupMesh");
- GroupMesh->setTitle(tr("SMESH_MESH" ));
- GroupMesh->setMinimumSize(QSize(0, 0));
- GroupMesh->setFrameShape(QGroupBox::Box);
- GroupMesh->setFrameShadow(QGroupBox::Sunken);
+
+ // Controls for mesh defining
+ GroupMesh = new QGroupBox(this, "GroupMesh");
+ GroupMesh->setTitle(tr("SMESH_SELECT_WHOLE_MESH"));
GroupMesh->setColumnLayout(0, Qt::Vertical);
GroupMesh->layout()->setSpacing(0);
GroupMesh->layout()->setMargin(0);
- GroupMeshLayout = new QGridLayout (GroupMesh->layout());
+ GroupMeshLayout = new QGridLayout(GroupMesh->layout());
GroupMeshLayout->setAlignment(Qt::AlignTop);
GroupMeshLayout->setSpacing(6);
GroupMeshLayout->setMargin(11);
- TextLabelMesh = new QLabel (GroupMesh, "TextLabelMesh");
- TextLabelMesh->setText(tr("SMESH_MESH"));
- TextLabelMesh->setMinimumSize(QSize(50, 0));
- TextLabelMesh->setFrameShape(QLabel::NoFrame);
- TextLabelMesh->setFrameShadow(QLabel::Plain);
- GroupMeshLayout->addWidget(TextLabelMesh, 0, 0);
- SelectButton = new QPushButton (GroupMesh, "SelectButton");
- SelectButton->setText(tr(""));
- SelectButton->setPixmap(image1);
- SelectButton->setToggleButton(FALSE);
- GroupMeshLayout->addWidget(SelectButton, 0, 1);
- LineEditMesh = new QLineEdit (GroupMesh, "LineEditMesh");
+
+ TextLabelName = new QLabel(GroupMesh, "TextLabelName");
+ TextLabelName->setText(tr("SMESH_NAME"));
+ GroupMeshLayout->addWidget(TextLabelName, 0, 0);
+
+ SelectMeshButton = new QPushButton(GroupMesh, "SelectMeshButton");
+ SelectMeshButton->setPixmap(IconSelect);
+ GroupMeshLayout->addWidget(SelectMeshButton, 0, 1);
+
+ LineEditMesh = new QLineEdit(GroupMesh, "LineEditMesh");
LineEditMesh->setReadOnly(true);
GroupMeshLayout->addWidget(LineEditMesh, 0, 2);
+
DlgLayout->addWidget(GroupMesh, 1, 0);
- myHelpFileName = "merge_elements.htm";
+ /***************************************************************/
+
+ // Controls for coincident elements detecting
+ GroupCoincident = new QGroupBox(this, "GroupCoincident");
+ GroupCoincident->setTitle(tr("COINCIDENT_NODES"));
+ GroupCoincident->setColumnLayout(0, Qt::Vertical);
+ GroupCoincident->layout()->setSpacing(0);
+ GroupCoincident->layout()->setMargin(0);
+ GroupCoincidentLayout = new QGridLayout(GroupCoincident->layout());
+ GroupCoincidentLayout->setAlignment(Qt::AlignTop);
+ GroupCoincidentLayout->setSpacing(6);
+ GroupCoincidentLayout->setMargin(11);
+
+ if (myAction == 0) { // case merge nodes
+ TextLabelTolerance = new QLabel(GroupCoincident, "TextLabelTolerance");
+ TextLabelTolerance->setText(tr("SMESH_TOLERANCE"));
+ TextLabelTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
+ GroupCoincidentLayout->addWidget(TextLabelTolerance, 0, 0);
+
+ SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident, "SpinBoxTolerance");
+ GroupCoincidentLayout->addWidget(SpinBoxTolerance, 0, 1);
+ }
+
+ DetectButton = new QPushButton(GroupCoincident, "DetectButton");
+ DetectButton->setText(tr("DETECT"));
+ DetectButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
+ GroupCoincidentLayout->addWidget(DetectButton, 0, 2);
+
+ ListCoincident = new QListBox(GroupCoincident, "ListCoincident");
+ ListCoincident->setSelectionMode(QListBox::Extended);
+ if (myAction == 0) // case merge nodes
+ GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 1, 3, 0, 1);
+ else // case merge elements
+ GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 0, 3, 0, 1);
+
+ QSpacerItem* spacer1 = new QSpacerItem(20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding);
+ GroupCoincidentLayout->addItem(spacer1, 1, 2);
+
+ AddGroupButton = new QPushButton(GroupCoincident, "AddGroupButton");
+ AddGroupButton->setText(tr("SMESH_BUT_ADD"));
+ GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2);
+
+ RemoveGroupButton = new QPushButton(GroupCoincident, "RemoveGroupButton");
+ RemoveGroupButton->setText(tr("SMESH_BUT_REMOVE"));
+ GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+
+ SelectAllCB = new QCheckBox(GroupCoincident, "SelectAllCB");
+ SelectAllCB->setText(tr("SELECT_ALL"));
+ GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0);
+
+ DlgLayout->addWidget(GroupCoincident, 2, 0);
+
+ /***************************************************************/
+
+ // Controls for editing the selected group
+ GroupEdit = new QGroupBox(this, "GroupEdit");
+ GroupEdit->setTitle(tr("EDIT_SELECTED_GROUP"));
+ GroupEdit->setColumnLayout(0, Qt::Vertical);
+ GroupEdit->layout()->setSpacing(0);
+ GroupEdit->layout()->setMargin(0);
+ GroupEditLayout = new QGridLayout(GroupEdit->layout());
+ GroupEditLayout->setAlignment(Qt::AlignTop);
+ GroupEditLayout->setSpacing(6);
+ GroupEditLayout->setMargin(11);
+
+ ListEdit = new QListBox(GroupEdit, "ListEdit");
+ ListEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
+ ListEdit->setRowMode(QListBox::FixedNumber);
+ ListEdit->setMinimumHeight(ListEdit->sizeHint().height());
+ ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
+ ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
+ ListEdit->setSelectionMode(QListBox::Extended);
+ GroupEditLayout->addMultiCellWidget(ListEdit, 0, 1, 0, 0);
+
+ AddElemButton = new QPushButton(GroupEdit, "AddElemButton");
+ AddElemButton->setPixmap(IconAdd);
+ GroupEditLayout->addWidget(AddElemButton, 0, 1);
+
+ RemoveElemButton = new QPushButton(GroupEdit, "RemoveElemButton");
+ RemoveElemButton->setPixmap(IconRemove);
+ GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
+
+ SetFirstButton = new QPushButton(GroupEdit, "SetFirstButton");
+ SetFirstButton->setIconSet(QPixmap(IconFirst));
+ SetFirstButton->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ GroupEditLayout->addMultiCellWidget(SetFirstButton, 1, 1, 1, 2);
+
+ DlgLayout->addWidget(GroupEdit, 3, 0);
Init(); // Initialisations
}
SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
{
// no need to delete child widgets, Qt does it all for us
+ delete myIdPreview;
}
//=================================================================================
//=================================================================================
void SMESHGUI_EditMeshDlg::Init()
{
- GroupMesh->show();
- mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+ if (myAction == 0) {
+ SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.1, 3);
+ SpinBoxTolerance->SetValue(1e-05);
+ }
+
+ RadioButton->setChecked(TRUE);
+
+ myEditCurrentArgument = (QWidget*)LineEditMesh;
- myMesh = SMESH::SMESH_Mesh::_nil();
+ myActor = 0;
+ mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
- myMeshFilter = new SMESH_TypeFilter (MESH);
+ mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+ mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+ myIsBusy = false;
+
+ // Costruction of the logical filter
+ SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+ SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP);
+
+ QPtrList<SUIT_SelectionFilter> aListOfFilters;
+ if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+ if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter);
- // signals and slots connections
- connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+ myMeshOrSubMeshOrGroupFilter =
+ new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+
+ /* signals and slots connections */
+ connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
- connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+ connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
- connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
+ connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+ connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
+ connect(ListCoincident, SIGNAL (selectionChanged()), this, SLOT(onSelectGroup()));
+ connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
+ connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
+ connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
+ connect(ListEdit, SIGNAL (selectionChanged()), this, SLOT(onSelectElementFromGroup()));
+ connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
+ connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
+ connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
+ connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+ /* to close dialog if study change */
+ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
- connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
- connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()) , this, SLOT(ClickOnCancel()));
+ this->show(); /* displays Dialog */
+
+ SetFirstButton->setEnabled(false);
+ buttonOk->setEnabled(false);
+ buttonApply->setEnabled(false);
- this->show(); // displays Dialog
+ // Init Mesh field from selection
+ SelectionIntoArgument();
- LineEditMesh->setFocus();
- mySelectionMgr->clearFilters();
- mySelectionMgr->installFilter(myMeshFilter);
+ // dialog customization
+ if (myAction == 1) {
+ setCaption(tr("SMESH_MERGE_ELEMENTS"));
+ GroupConstructors->setTitle(tr("SMESH_MERGE_ELEMENTS"));
+ GroupCoincident->setTitle(tr("COINCIDENT_ELEMENTS"));
+ }
+
+ myHelpFileName = "merge_elements.htm";
+}
- SelectionIntoArgument();
+//=================================================================================
+// function : FindGravityCenter()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
+ list< gp_XYZ > & theGrCentersXYZ)
+{
+ if (!myActor)
+ return;
+
+ SMDS_Mesh* aMesh = 0;
+ aMesh = myActor->GetObject()->GetMesh();
+ if (!aMesh)
+ return;
+
+ int nbNodes;
+
+ TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+ for( ; idIter.More(); idIter.Next() ) {
+ const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
+ if ( !anElem )
+ continue;
+
+ gp_XYZ anXYZ(0., 0., 0.);
+ SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
+ for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
+ const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
+ }
+ anXYZ.Divide( nbNodes );
+
+ theGrCentersXYZ.push_back( anXYZ );
+ }
}
//=================================================================================
// function : ClickOnApply()
// purpose :
//=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnApply()
+bool SMESHGUI_EditMeshDlg::ClickOnApply()
{
- if (!myMesh->_is_nil()) {
- try {
- QApplication::setOverrideCursor(Qt::waitCursor);
+ if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
+ return false;
- if (myAction == 1) {
- SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
- aMeshEditor->MergeEqualElements();
- }
+ try {
+ SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+ QApplication::setOverrideCursor(Qt::waitCursor);
+
+ SMESH::long_array_var anIds = new SMESH::long_array;
+ SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
- QApplication::restoreOverrideCursor();
- } catch(...) {
+ aGroupsOfElements->length(ListCoincident->count());
+ QListBoxItem* item = ListCoincident->firstItem();
+
+ int anArrayNum = 0;
+ while (item) {
+ QStringList aListIds = QStringList("");
+ aListIds = QStringList::split(" ", item->text(), false);
+
+ anIds->length(aListIds.count());
+ for (int i = 0; i < aListIds.count(); i++)
+ anIds[i] = aListIds[i].toInt();
+
+ aGroupsOfElements[anArrayNum++] = anIds.inout();
+ item = item->next();
}
- //mySelectionMgr->clearSelected();
- SMESH::UpdateView();
+ if( myAction == 0 )
+ aMeshEditor->MergeNodes (aGroupsOfElements.inout());
+ else
+ aMeshEditor->MergeElements (aGroupsOfElements.inout());
+
+ QApplication::restoreOverrideCursor();
+ } catch(...) {
}
+
+ SMESH::UpdateView();
+
+ onDetect();
+ return true;
}
//=================================================================================
//=================================================================================
void SMESHGUI_EditMeshDlg::ClickOnOk()
{
- ClickOnApply();
- ClickOnCancel();
+ if (ClickOnApply())
+ ClickOnCancel();
}
//=================================================================================
//=================================================================================
void SMESHGUI_EditMeshDlg::ClickOnCancel()
{
- //mySelectionMgr->clearSelected();
+ myIdPreview->SetPointsLabeled(false);
mySelectionMgr->clearFilters();
+ //mySelectionMgr->clearSelected();
+ SMESH::SetPointRepresentation(false);
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(ActorSelection);
disconnect(mySelectionMgr, 0, this, 0);
mySMESHGUI->ResetState();
reject();
}
//=================================================================================
-// function : SelectionIntoArgument()
-// purpose : Called when selection as changed or other case
+// function : onEditGroup()
+// purpose :
//=================================================================================
-void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+void SMESHGUI_EditMeshDlg::onEditGroup()
+{
+ int nbSel = 0;
+ for (int i = 0; i < ListCoincident->count(); i++) {
+ if (ListCoincident->isSelected(i))
+ nbSel++;
+ if (nbSel > 1) {
+ ListEdit->clear();
+ return;
+ }
+ }
+ if (nbSel == 0) {
+ ListEdit->clear();
+ return;
+ }
+
+ QString aNewIds = "";
+
+ QListBoxItem* anItem;
+ for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next())
+ aNewIds+=QString(" %1").arg(anItem->text());
+
+ ListCoincident->changeItem(aNewIds, ListCoincident->currentItem());
+ ListCoincident->setSelected(ListCoincident->currentItem(), true);
+
+}
+
+//=================================================================================
+// function : updateControls()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::updateControls()
{
- if (!GroupButtons->isEnabled()) // inactive
+ if (ListEdit->count() == 0)
+ SetFirstButton->setEnabled(false);
+ bool enable = !(myMesh->_is_nil()) && ListCoincident->count();
+ buttonOk->setEnabled(enable);
+ buttonApply->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onDetect()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onDetect()
+{
+ if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
return;
- QString aString = "";
+ try {
+ SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+ QApplication::setOverrideCursor(Qt::waitCursor);
+ ListCoincident->clear();
+ ListEdit->clear();
+
+ SMESH::array_of_long_array_var aGroupsArray;
+
+ switch (myAction) {
+ case 0 :
+ if(!mySubMeshOrGroup->_is_nil())
+ aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray);
+ else
+ aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray);
+ break;
+ case 1 :
+ if(!mySubMeshOrGroup->_is_nil())
+ aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray);
+ else
+ aMeshEditor->FindEqualElements(myMesh, aGroupsArray);
+ break;
+ }
+
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < aGroupsArray->length(); i++) {
+ SMESH::long_array& aGroup = aGroupsArray[i];
+
+ QString anIDs;
+ for (int j = 0; j < aGroup.length(); j++)
+ anIDs+=QString(" %1").arg(aGroup[j]);
+
+ anItem = new QListBoxText(anIDs);
+ ListCoincident->insertItem(anItem);
+ }
+ QApplication::restoreOverrideCursor();
+ } catch(...) {
+ }
+
+ ListCoincident->selectAll(true);
+ updateControls();
+}
+
+//=================================================================================
+// function : onSelectGroup()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectGroup()
+{
+ if (myIsBusy || !myActor)
+ return;
+ myEditCurrentArgument = (QWidget*)ListCoincident;
+ ListEdit->clear();
+
+ TColStd_MapOfInteger anIndices;
+ QListBoxItem* anItem;
+ int NbOfSelected = 0;
+ for (anItem = ListCoincident->firstItem(); anItem != 0; anItem = anItem->next()) {
+ if (anItem->isSelected()) {
+ QStringList aListIds = QStringList("");
+ aListIds = QStringList::split(" ", anItem->text(), false);
+ for (int i = 0; i < aListIds.count(); i++)
+ anIndices.Add(aListIds[i].toInt());
+ NbOfSelected++;
+ ListEdit->clear();
+ if (NbOfSelected == 1) {
+ ListEdit->insertStringList(aListIds);
+ ListEdit->selectAll(true);
+ }
+ }
+ }
+ mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
SALOME_ListIO aList;
- mySelectionMgr->selectedObjects(aList);
- int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-
- // mesh
- if (nbSel != 1) {
- myMesh = SMESH::SMESH_Mesh::_nil();
- aString = "";
- } else {
- Handle(SALOME_InteractiveObject) IO = aList.First();
- myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
- if (myMesh->_is_nil())
- aString = "";
+ aList.Append(myActor->getIO());
+ mySelectionMgr->setSelectedObjects(aList,false);
+
+ if (myAction == 0) {
+ myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+ myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+ }
+ else {
+ list< gp_XYZ > aGrCentersXYZ;
+ FindGravityCenter(anIndices, aGrCentersXYZ);
+ myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
+ myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+ }
+
+ updateControls();
+}
+
+//=================================================================================
+// function : onSelectAll()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled)
+{
+ ListCoincident->selectAll(isToggled);
+}
+
+//=================================================================================
+// function : onSelectElementFromGroup()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectElementFromGroup()
+{
+ if (myIsBusy || !myActor)
+ return;
+
+ int nbSel = 0;
+ TColStd_MapOfInteger anIndices;
+ QListBoxItem* anItem;
+ for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
+ if (anItem->isSelected()) {
+ int anId = anItem->text().toInt();
+ anIndices.Add(anId);
+ nbSel++;
+ if (nbSel == 1)
+ SetFirstButton->setEnabled(true);
+ }
+ }
+ if (nbSel == 0 || nbSel > 1)
+ SetFirstButton->setEnabled(false);
+
+ mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
+ SALOME_ListIO aList;
+ aList.Append(myActor->getIO());
+ mySelectionMgr->setSelectedObjects(aList);
+
+ if (myAction == 0) {
+ myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+ myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+ }
+ else {
+ list< gp_XYZ > aGrCentersXYZ;
+ FindGravityCenter(anIndices, aGrCentersXYZ);
+ myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
+ myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+ }
+}
+
+//=================================================================================
+// function : onAddGroup()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddGroup()
+{
+ if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+ return;
+
+ QString anIDs = "";
+ SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+
+ ListCoincident->clearSelection();
+ QListBoxItem* anItem = new QListBoxText(anIDs);
+ ListCoincident->insertItem(anItem);
+ int nbGroups = ListCoincident->count();
+ if (nbGroups) {
+ ListCoincident->setCurrentItem(nbGroups-1);
+ ListCoincident->setSelected(nbGroups-1, true);
+ }
+ else {
+ ListCoincident->setCurrentItem(0);
+ ListCoincident->setSelected(0, true);
+ }
+
+ updateControls();
+}
+
+//=================================================================================
+// function : onRemoveGroup()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveGroup()
+{
+ if (myEditCurrentArgument != (QWidget*)ListCoincident)
+ return;
+ myIsBusy = true;
+
+ for (int i = ListCoincident->count(); i > 0; i--)
+ if (ListCoincident->isSelected(i-1))
+ ListCoincident->removeItem(i-1);
+
+ ListEdit->clear();
+ updateControls();
+
+ myIsBusy = false;
+}
+
+//=================================================================================
+// function : onAddElement()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddElement()
+{
+ if (!myActor)
+ return;
+ myIsBusy = true;
+
+ QString aListStr = "";
+ int aNbNnodes = 0;
+
+ aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+ if (aNbNnodes < 1)
+ return;
+
+ QStringList aNodes = QStringList::split(" ", aListStr);
+ QListBoxItem* anItem = 0;
+
+ for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
+ anItem = ListEdit->findItem(*it, Qt::ExactMatch);
+ if (!anItem) {
+ anItem = new QListBoxText(*it);
+ ListEdit->insertItem(anItem);
+ }
+ ListEdit->setSelected(anItem, true);
+ }
+
+ myIsBusy = false;
+ onEditGroup();
+}
+
+//=================================================================================
+// function : onRemoveElement()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveElement()
+{
+ if (myEditCurrentArgument != (QWidget*)ListCoincident)
+ return;
+ myIsBusy = true;
+
+ for (int i = ListEdit->count(); i > 0; i--)
+ if (ListEdit->isSelected(i-1))
+ ListEdit->removeItem(i-1);
+
+ myIsBusy = false;
+ onEditGroup();
+}
+
+//=================================================================================
+// function : onSetFirst()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSetFirst()
+{
+ if (myEditCurrentArgument != (QWidget*)ListCoincident)
+ return;
+ myIsBusy = true;
+
+ QListBoxItem* anItem;
+ for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
+ if (anItem->isSelected()) {
+ ListEdit->takeItem(anItem);
+ ListEdit->insertItem(anItem, 0);
+ }
+ }
+
+ myIsBusy = false;
+ onEditGroup();
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SetEditCurrentArgument()
+{
+ QPushButton* send = (QPushButton*)sender();
+
+ disconnect(mySelectionMgr, 0, this, 0);
+ mySelectionMgr->clearSelected();
+ mySelectionMgr->clearFilters();
+
+ if (send == SelectMeshButton) {
+ myEditCurrentArgument = (QWidget*)LineEditMesh;
+ SMESH::SetPointRepresentation(false);
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(ActorSelection);
+ mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
}
- LineEditMesh->setText(aString);
+ myEditCurrentArgument->setFocus();
+ connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+ SelectionIntoArgument();
+}
- bool isEnabled = (!myMesh->_is_nil());
- buttonOk->setEnabled(isEnabled);
- buttonApply->setEnabled(isEnabled);
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+{
+ if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
+ QString aString = "";
+ LineEditMesh->setText(aString);
+
+ ListCoincident->clear();
+ ListEdit->clear();
+ myActor = 0;
+
+ int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+ if (nbSel != 1)
+ return;
+
+ SALOME_ListIO aList;
+ mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
+
+ Handle(SALOME_InteractiveObject) IO = aList.First();
+ myMesh = SMESH::GetMeshByIO(IO);
+
+ if (myMesh->_is_nil())
+ return;
+
+ myActor = SMESH::FindActorByEntry(IO->getEntry());
+ if (!myActor)
+ myActor = SMESH::FindActorByObject(myMesh);
+ if(!myActor)
+ return;
+
+ mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+
+ if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+ !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+ !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+ mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+
+ LineEditMesh->setText(aString);
+
+ if (myAction == 0) {
+ SMESH::SetPointRepresentation(true);
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(NodeSelection);
+ }
+ else
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(CellSelection);
+ }
}
//=================================================================================
if (GroupConstructors->isEnabled()) {
GroupConstructors->setEnabled(false);
GroupMesh->setEnabled(false);
+ GroupCoincident->setEnabled(false);
+ GroupEdit->setEnabled(false);
GroupButtons->setEnabled(false);
mySMESHGUI->ResetState();
mySMESHGUI->SetActiveDialogBox(0);
mySMESHGUI->EmitSignalDeactivateDialog();
GroupConstructors->setEnabled(true);
GroupMesh->setEnabled(true);
+ GroupCoincident->setEnabled(true);
+ GroupEdit->setEnabled(true);
GroupButtons->setEnabled(true);
mySMESHGUI->SetActiveDialogBox((QDialog*)this);
// function : enterEvent()
// purpose :
//=================================================================================
-void SMESHGUI_EditMeshDlg::enterEvent(QEvent* e)
+void SMESHGUI_EditMeshDlg::enterEvent(QEvent*)
{
- if (GroupConstructors->isEnabled())
- return;
- ActivateThisDialog();
+ if (!GroupConstructors->isEnabled())
+ ActivateThisDialog();
}
//=================================================================================
// function : closeEvent()
// purpose :
//=================================================================================
-void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent* e)
+void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*)
{
/* same than click on cancel button */
this->ClickOnCancel();
//function : hideEvent
//purpose : caused by ESC key
//=======================================================================
-void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent * e)
+void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *)
{
if (!isMinimized())
ClickOnCancel();
}
-
//=================================================================================
// function : keyPressEvent()
// purpose :
//=================================================================================
-void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e )
+void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e)
{
QDialog::keyPressEvent( e );
if ( e->isAccepted() )
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#ifndef DIALOGBOX_GETMESH_H
-#define DIALOGBOX_GETMESH_H
+#ifndef SMESHGUI_EditMeshDlg_H
+#define SMESHGUI_EditMeshDlg_H
#include "SMESH_SMESHGUI.hxx"
#include <qdialog.h>
// Open CASCADE Includes
+#include <gp_XYZ.hxx>
class QGridLayout;
class QButtonGroup;
class QLineEdit;
class QPushButton;
class QRadioButton;
+class QCheckBox;
+class QListBox;
class SMESHGUI;
+class SMESHGUI_SpinBox;
+class SMESH_Actor;
+class SALOME_Actor;
+class SVTK_ViewWindow;
+class SVTK_Selector;
+
+namespace SMESH{
+ struct TIdPreview;
+}
// IDL Headers
#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
//=================================================================================
// class : SMESHGUI_EditMeshDlg
public:
SMESHGUI_EditMeshDlg (SMESHGUI * theModule,
- const char* title,
- const char* icon,
int theAction);
~SMESHGUI_EditMeshDlg();
void enterEvent (QEvent*); /* mouse enter the QWidget */
void hideEvent (QHideEvent*); /* ESC key */
void keyPressEvent(QKeyEvent*);
+ void onEditGroup();
+
+ void FindGravityCenter(TColStd_MapOfInteger & ElemsIdMap,
+ list< gp_XYZ > & GrCentersXYZ);
+ // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
private:
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
+ SVTK_Selector* mySelector;
+
+ QWidget* myEditCurrentArgument;
- SMESH::SMESH_Mesh_var myMesh;
- SUIT_SelectionFilter* myMeshFilter;
+ SMESH::SMESH_Mesh_var myMesh;
+ SMESH::SMESH_IDSource_var mySubMeshOrGroup;
+ SMESH_Actor* myActor;
+ SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
+
+ SMESH::TIdPreview* myIdPreview;
int myAction;
+ bool myIsBusy;
// Widgets
- QButtonGroup* GroupConstructors;
- QRadioButton* Constructor1;
-
- QGroupBox* GroupButtons;
- QPushButton* buttonOk;
- QPushButton* buttonCancel;
- QPushButton* buttonApply;
- QPushButton* buttonHelp;
-
- QGroupBox* GroupMesh;
- QLabel* TextLabelMesh;
- QPushButton* SelectButton;
- QLineEdit* LineEditMesh;
-
+ QButtonGroup* GroupConstructors;
+ QRadioButton* RadioButton;
+
+ QGroupBox* GroupButtons;
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+ QPushButton* buttonApply;
+ QPushButton* buttonHelp;
+
+ QGroupBox* GroupMesh;
+ QLabel* TextLabelName;
+ QPushButton* SelectMeshButton;
+ QLineEdit* LineEditMesh;
+
+ QGroupBox* GroupCoincident;
+ QLabel* TextLabelTolerance;
+ SMESHGUI_SpinBox* SpinBoxTolerance;
+ QPushButton* DetectButton;
+ QListBox* ListCoincident;
+ QPushButton* AddGroupButton;
+ QPushButton* RemoveGroupButton;
+ QCheckBox* SelectAllCB;
+
+ QGroupBox* GroupEdit;
+ QListBox* ListEdit;
+ QPushButton* AddElemButton;
+ QPushButton* RemoveElemButton;
+ QPushButton* SetFirstButton;
+
//protected:
QGridLayout* DlgLayout;
QGridLayout* GroupConstructorsLayout;
QGridLayout* GroupButtonsLayout;
QGridLayout* GroupMeshLayout;
+ QGridLayout* GroupCoincidentLayout;
+ QGridLayout* GroupEditLayout;
QString myHelpFileName;
private slots:
void ClickOnOk();
void ClickOnCancel();
- void ClickOnApply();
+ bool ClickOnApply();
void ClickOnHelp();
- void SelectionIntoArgument();
- void DeactivateActiveDialog();
- void ActivateThisDialog();
+ void updateControls();
+ void onDetect();
+ void onAddGroup();
+ void onRemoveGroup();
+ void onSelectGroup();
+ void onSelectAll(bool isToggled);
+ void onSelectElementFromGroup();
+ void onAddElement();
+ void onRemoveElement();
+ void onSetFirst();
+ void SetEditCurrentArgument();
+ void SelectionIntoArgument() ;
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog() ;
+
};
-#endif // DIALOGBOX_GETMESH_H
+#endif // SMESHGUI_EditMeshDlg_H
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
SelectBasePointButton->setPixmap(selectImage);
XLab = new QLabel(tr("SMESH_X"), BasePointGrp);
+ XLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
XSpin = new SMESHGUI_SpinBox(BasePointGrp);
YLab = new QLabel(tr("SMESH_Y"), BasePointGrp);
+ YLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
YSpin = new SMESHGUI_SpinBox(BasePointGrp);
ZLab = new QLabel(tr("SMESH_Z"), BasePointGrp);
+ ZLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
ZSpin = new SMESHGUI_SpinBox(BasePointGrp);
// layouting
// try to get selected elements IDs
QString aString;
//int aNbUnits = SMESH::GetNameOfSelectedElements(mySelectionMgr, aString);
- SMESH::GetNameOfSelectedElements(mySelector, myMeshActor->getIO(), aString);
+ SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
ElementsLineEdit->setText(aString);
}
} else if (myEditCurrentArgument == PathMeshLineEdit) {
QLabel* StartPointLab;
QToolButton* SelectStartPointButton;
QLineEdit* StartPointLineEdit;
+ QCheckBox* LinearAnglesCheck;
QCheckBox* AnglesCheck;
QGroupBox* AnglesGrp;
QListBox* AnglesList;
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
aNbElements = anElementsIds->length();
}
} else {
- aNbElements = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+ aNbElements = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
myElementsId = aString;
}
aCriterion == FT_BelongToGeom ||
aCriterion == FT_BelongToPlane ||
aCriterion == FT_BelongToCylinder ||
+ aCriterion == FT_BelongToGenSurface ||
aCriterion == FT_LyingOnGeom) {
if (aTable->text(i, 2).isEmpty()) {
if (theMess)
aCriterionType != FT_BelongToGeom &&
aCriterionType != FT_BelongToPlane &&
aCriterionType != FT_BelongToCylinder &&
+ aCriterionType != FT_BelongToGenSurface &&
aCriterionType != FT_LyingOnGeom)
{
theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->GetValue();
theCriterion.Type != FT_BelongToGeom &&
theCriterion.Type != FT_BelongToPlane &&
theCriterion.Type != FT_BelongToCylinder &&
+ theCriterion.Type != FT_BelongToGenSurface &&
theCriterion.Type != FT_LyingOnGeom &&
theCriterion.Type != FT_FreeBorders &&
theCriterion.Type != FT_FreeEdges &&
if (theCriterion.Compare == FT_EqualTo ||
theCriterion.Type == FT_BelongToPlane ||
- theCriterion.Type == FT_BelongToCylinder)
+ theCriterion.Type == FT_BelongToCylinder ||
+ theCriterion.Type == FT_BelongToGenSurface)
{
QTableItem* anItem = aTable->item(theRow, 0);
if (!myAddWidgets.contains(anItem))
aCriterionType == SMESH::FT_BelongToGeom ||
aCriterionType == SMESH::FT_BelongToPlane ||
aCriterionType == SMESH::FT_BelongToCylinder ||
+ aCriterionType == SMESH::FT_BelongToGenSurface ||
aCriterionType == SMESH::FT_LyingOnGeom)
{
QMap<int, QString> aMap;
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+ aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
}
return aCriteria;
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+ aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
}
return aCriteria;
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+ aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D");
aCriteria[ SMESH::FT_MultiConnection2D] = tr("MULTI2D_BORDERS");
if (aType == FT_BelongToGeom ||
aType == FT_BelongToPlane ||
aType == FT_BelongToCylinder ||
+ aType == FT_BelongToGenSurface ||
aType == FT_LyingOnGeom) {
QString aName;
myTable->GetThreshold(i, aName);
return false;
}
- if (aType == FT_BelongToCylinder || aType == FT_BelongToPlane) {
+ if (aType == FT_BelongToCylinder ||
+ aType == FT_BelongToPlane ||
+ aType == FT_BelongToGenSurface ) {
CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
//GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
myTable->GetCriterionType(aRow) != FT_BelongToGeom &&
myTable->GetCriterionType(aRow) != FT_BelongToPlane &&
myTable->GetCriterionType(aRow) != FT_BelongToCylinder &&
+ myTable->GetCriterionType(aRow) != FT_BelongToGenSurface &&
myTable->GetCriterionType(aRow) != FT_LyingOnGeom)
return;
(myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
myTable->GetCriterionType(aRow) == FT_BelongToPlane ||
myTable->GetCriterionType(aRow) == FT_BelongToCylinder ||
+ myTable->GetCriterionType(aRow) == FT_BelongToGenSurface ||
myTable->GetCriterionType(aRow) == FT_LyingOnGeom)) {
if (myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
+ myTable->GetCriterionType(aRow) == FT_BelongToGenSurface ||
myTable->GetCriterionType(aRow) == FT_LyingOnGeom) {
mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
}
return GEOM::GEOM_Object::_nil();
}
+
+ GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
+ long theID)
+ {
+ GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+ _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+ if (!aStudy || geomGen->_is_nil())
+ return GEOM::GEOM_Object::_nil();
+ GEOM::GEOM_IShapesOperations_var aShapesOp = geomGen->GetIShapesOperations(aStudy->StudyId());
+ if (aShapesOp->_is_nil())
+ return GEOM::GEOM_Object::_nil();
+ GEOM::GEOM_Object_var subShape = aShapesOp->GetSubShape (theMainShape,theID);
+ return subShape._retn();
+ }
}
SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh (_PTR(SObject) theSObject);
SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom (_PTR(SObject) theSO);
+
+ SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
+ long theID);
}
#endif
//=================================================================================
void SMESHGUI_GroupDlg::updateButtons()
{
- bool enable;
+ bool enable = !myName->text().stripWhiteSpace().isEmpty();
- if (myGrpTypeId == 0)
- enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0;
- else if (myGrpTypeId == 1)
- {
- bool isEditMode = !CORBA::is_nil( myGroupOnGeom );
- enable = !myName->text().stripWhiteSpace().isEmpty() && (myGeomObjects->length() > 0 || isEditMode);
+ if (myGrpTypeId == 0) {
+ enable = enable && myElements->count() > 0;
+ enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
+ }
+ else if (myGrpTypeId == 1) {
+ if (CORBA::is_nil(myGroupOnGeom)) { // creation mode
+ enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil();
}
+ }
+
QPushButton* aBtn;
aBtn = (QPushButton*) child("ok", "QPushButton");
if (aBtn) aBtn->setEnabled(enable);
if (mySMESHGUI->isActiveStudyLocked())
return false;
- if (myGrpTypeId == 0 &&
- !myName->text().stripWhiteSpace().isEmpty() &&
- myElements->count() > 0) {
+ if (myName->text().stripWhiteSpace().isEmpty())
+ return false;
+
+ if (myGrpTypeId == 0) { // on mesh elements
+ if (!myElements->count())
+ return false;
+
mySelectionMgr->clearSelected();
- if (myGroup->_is_nil()) {
+
+ if (myGroup->_is_nil()) { // creation
+ if (myMesh->_is_nil())
+ return false;
+
SMESH::ElementType aType = SMESH::ALL;
- switch(myTypeId) {
+ switch (myTypeId) {
case 0: aType = SMESH::NODE; break;
case 1: aType = SMESH::EDGE; break;
case 2: aType = SMESH::FACE; break;
case 3: aType = SMESH::VOLUME; break;
}
+
SMESH::long_array_var anIdList = new SMESH::long_array;
int i, k = myElements->count();
anIdList->length(k);
myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
myGroup->Add(anIdList.inout());
-
+
int aColorNumber = myColorSpinBox->value();
myGroup->SetColorNumber(aColorNumber);
-
+
_PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-
- SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
-
+ SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
+
/* init for next operation */
myName->setText("");
myColorSpinBox->setValue(0);
myElements->clear();
myGroup = SMESH::SMESH_Group::_nil();
- } else {
+ } else { // edition
myGroup->SetName(myName->text());
int aColorNumber = myColorSpinBox->value();
SMESH::UpdateView(); // asv: fix of BUG PAL5515
mySelectionMgr->clearSelected();
return true;
- } else if (myGrpTypeId == 1 &&
- !myName->text().stripWhiteSpace().isEmpty() &&
- (myGeomObjects->length() > 0 || !CORBA::is_nil(myGroupOnGeom)))
- {
- if (myGroupOnGeom->_is_nil()) {
+ }
+ else if (myGrpTypeId == 1) { // on geom object
+ if (CORBA::is_nil(myGroupOnGeom)) { // creation
+ if (myMesh->_is_nil() || !myGeomObjects->length())
+ return false;
+
SMESH::ElementType aType = SMESH::ALL;
switch (myTypeId) {
case 0: aType = SMESH::NODE; break;
case 2: aType = SMESH::FACE; break;
case 3: aType = SMESH::VOLUME; break;
}
-
+
_PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
GEOM::GEOM_IGroupOperations_var aGroupOp =
SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
-
- if (myGeomObjects->length() == 1)
+
+ if (myGeomObjects->length() == 1) {
myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomObjects[0]);
- else
- {
- SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
- if ( aSMESHGen->_is_nil() )
- return false;
+ }
+ else {
+ SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
+ if ( aSMESHGen->_is_nil() )
+ return false;
+
+ // create a geometry group
+ GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+ _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+
+ if (geomGen->_is_nil() || !aStudy)
+ return false;
+
+ GEOM::GEOM_IGroupOperations_var op =
+ geomGen->GetIGroupOperations(aStudy->StudyId());
+ if (op->_is_nil())
+ return false;
+
+ // check and add all selected GEOM objects: they must be
+ // a sub-shapes of the main GEOM and must be of one type
+ TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
+ for ( int i =0; i < myGeomObjects->length(); i++) {
+ TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
+ if (i == 0)
+ aGroupType = aSubShapeType;
+ else if (aSubShapeType != aGroupType) {
+ aGroupType = TopAbs_SHAPE;
+ break;
+ }
+ }
- // create a geometry group
- GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
- _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+ GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
+ GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
+ op->UnionList(aGroupVar, myGeomObjects);
+
+ if (op->IsDone()) {
+ // publish the GEOM group in study
+ QString aNewGeomGroupName ("Auto_group_for_");
+ aNewGeomGroupName += myName->text();
+ SALOMEDS::SObject_var aNewGroupSO =
+ geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, aNewGeomGroupName, aMeshShape);
+ }
+
+ myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(), aGroupVar);
+ }
- if (geomGen->_is_nil() || !aStudy)
- return false;
-
- GEOM::GEOM_IGroupOperations_var op =
- geomGen->GetIGroupOperations(aStudy->StudyId());
- if (op->_is_nil())
- return false;
-
- // check and add all selected GEOM objects: they must be
- // a sub-shapes of the main GEOM and must be of one type
- TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
- for ( int i =0; i < myGeomObjects->length(); i++)
- {
- TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
- if (i == 0)
- aGroupType = aSubShapeType;
- else if (aSubShapeType != aGroupType)
- {
- aGroupType = TopAbs_SHAPE;
- break;
- }
- }
-
- GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
- GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
- op->UnionList(aGroupVar, myGeomObjects);
-
- if (op->IsDone()) {
- // publish the GEOM group in study
- QString aNewGeomGroupName ("Auto_group_for_");
- aNewGeomGroupName += myName->text();
- SALOMEDS::SObject_var aNewGroupSO =
- geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, aNewGeomGroupName, aMeshShape);
- }
-
- myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(), aGroupVar);
- }
-
int aColorNumber = myColorSpinBox->value();
myGroupOnGeom->SetColorNumber(aColorNumber);
-
+
_PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
-
+
SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-
+
SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
-
+
/* init for next operation */
myName->setText("");
myColorSpinBox->setValue(0);
myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
}
- else
- {
- myGroupOnGeom->SetName(myName->text());
-
- int aColorNumber = myColorSpinBox->value();
- myGroupOnGeom->SetColorNumber(aColorNumber);
- }
-
+ else { // edition
+ myGroupOnGeom->SetName(myName->text());
+
+ int aColorNumber = myColorSpinBox->value();
+ myGroupOnGeom->SetColorNumber(aColorNumber);
+ }
+
mySMESHGUI->updateObjBrowser(true);
mySelectionMgr->clearSelected();
return true;
}
-
+
return false;
}
myGeomGroupBtn->setEnabled(false);
myGeomGroupLine->setEnabled(false);
myGeomGroupLine->setText("");
+ myGeomObjects = new GEOM::ListOfGO();
+ myGeomObjects->length(0);
+
if (myGeomGroupBtn->isOn())
myGeomGroupBtn->setOn(false);
if (!myCreate)
myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
myMesh = SMESH::SMESH_Mesh::_nil();
updateGeomPopup();
+ updateButtons();
myIsBusy = false;
return;
}
updateGeomPopup();
if (myMesh->_is_nil())
{
+ updateButtons();
myIsBusy = false;
return;
}
return;
} else if (myCurrentLineEdit == myGeomGroupLine) {
-
+
myGeomObjects = new GEOM::ListOfGO();
-
+
// The mesh SObject
_PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
-
+
if (aNbSel == 0 || !aMeshSO)
{
myGeomObjects->length(0);
+ updateButtons();
myIsBusy = false;
return;
}
-
+
myGeomObjects->length(aNbSel);
GEOM::GEOM_Object_var aGeomGroup;
if( !aSubMesh->_is_nil() )
aMesh = aSubMesh->GetFather();
_PTR(SObject) meshSO = SMESH::FindSObject( aMesh );
- SMESH::ModifiedMesh( meshSO, false);
+ SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0);
}
SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
}
if (res < SMESH::HYP_UNKNOWN_FATAL) {
_PTR(SObject) aSH = SMESH::FindSObject(aHyp);
if (SM && aSH) {
- SMESH::ModifiedMesh(SM, false);
+ SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
}
}
if (res > SMESH::HYP_OK) {
if (res < SMESH::HYP_UNKNOWN_FATAL) {
_PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
if (meshSO)
- SMESH::ModifiedMesh(meshSO, false);
+ SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
}
if (res > SMESH::HYP_OK) {
wc.suspend();
if (res < SMESH::HYP_UNKNOWN_FATAL) {
_PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
if (meshSO)
- SMESH::ModifiedMesh(meshSO, false);
+ SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
}
if (res > SMESH::HYP_OK) {
wc.suspend();
return listSOmesh;
}
-#define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( #enum ); break;
+#define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( "STATE_" #enum ); break;
QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
{
QString resMsg = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
for ( int i = 0; i < errors.length(); ++i ) {
const SMESH::AlgoStateError & error = errors[ i ];
+ const bool hasAlgo = ( strlen( error.algoName ) != 0 );
QString msg;
- switch( error.name ) {
- CASE2MESSAGE( MISSING_ALGO );
- CASE2MESSAGE( MISSING_HYPO );
- CASE2MESSAGE( NOT_CONFORM_MESH );
- CASE2MESSAGE( BAD_PARAM_VALUE );
- default: continue;
- }
+ if ( !hasAlgo )
+ msg = QObject::tr( "STATE_ALGO_MISSING" );
+ else
+ switch( error.state ) {
+ CASE2MESSAGE( HYP_MISSING );
+ CASE2MESSAGE( HYP_NOTCONFORM );
+ CASE2MESSAGE( HYP_BAD_PARAMETER );
+ default: continue;
+ }
// apply args to message:
// %1 - algo name
- if ( error.algoName.in() != 0 )
+ if ( hasAlgo )
msg = msg.arg( error.algoName.in() );
- // %2 - dimention
+ // %2 - dimension
msg = msg.arg( error.algoDim );
// %3 - global/local
msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_MakeNodeAtPointDlg.cxx
+// Author : Edward AGAPOV
+// Module : SMESH
+
+#include "SMESHGUI_MakeNodeAtPointDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESH_NumberFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+
+#include "GEOMBase.h"
+#include "GeometryGUI.h"
+
+#include "LightApp_DataOwner.h"
+#include "LightApp_SelectionMgr.h"
+#include "SALOMEDSClient_SObject.hxx"
+#include "SALOME_ListIO.hxx"
+#include "SUIT_Desktop.h"
+#include "SVTK_Selector.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_ViewModel.h"
+#include "SalomeApp_Tools.h"
+#include "SalomeApp_TypeFilter.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_MessageBox.h"
+
+// OCCT Includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+
+// QT Includes
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qapplication.h>
+#include <qstringlist.h>
+#include <qcheckbox.h>
+#include <qmessagebox.h>
+
+#include <vtkProperty.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#define SPACING 5
+#define MARGIN 10
+
+/*!
+ * \brief Dialog to publish a sub-shape of the mesh main shape
+ * by selecting mesh elements
+ */
+SMESHGUI_MakeNodeAtPointDlg::SMESHGUI_MakeNodeAtPointDlg()
+ : SMESHGUI_Dialog( 0, false, true )
+{
+ setCaption(tr("CAPTION"));
+
+ QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), MARGIN, SPACING);
+
+ QFrame* aMainFrame = createMainFrame (mainFrame());
+
+ aDlgLay->addWidget(aMainFrame);
+
+ aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//=======================================================================
+// function : createMainFrame()
+// purpose : Create frame containing dialog's input fields
+//=======================================================================
+QFrame* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
+{
+ QFrame* aFrame = new QFrame(theParent);
+
+ SUIT_ResourceMgr* rm = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+ QPixmap iconMoveNode (rm->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE")));
+ QPixmap iconSelect (rm->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+ // constructor
+
+ QButtonGroup* aPixGrp = new QButtonGroup(1, Qt::Vertical, tr("MESH_PASS_THROUGH_POINT"), aFrame);
+ aPixGrp->setExclusive(TRUE);
+ QRadioButton* aRBut = new QRadioButton(aPixGrp);
+ aRBut->setPixmap(iconMoveNode);
+ aRBut->setChecked(TRUE);
+
+ // coordinates
+
+ QGroupBox* aCoordGrp = new QGroupBox(1, Qt::Vertical, tr("SMESH_COORDINATES"), aFrame);
+ myCoordBtn = new QPushButton(aCoordGrp);
+ myCoordBtn->setPixmap(iconSelect);
+ myCoordBtn->setToggleButton(TRUE);
+
+ QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
+ aXLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ myX = new SMESHGUI_SpinBox(aCoordGrp);
+
+ QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
+ aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
+ myY = new SMESHGUI_SpinBox(aCoordGrp);
+
+ QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
+ aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
+ myZ = new SMESHGUI_SpinBox(aCoordGrp);
+
+ myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+ myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+ myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+
+ // Method selection
+
+ QButtonGroup* aMethodGrp = new QButtonGroup(1, Qt::Vertical, tr("METHOD"), aFrame);
+ aMethodGrp->setExclusive(TRUE);
+ myMoveRBtn = new QRadioButton(tr("MOVE_EXISTING_METHOD"), aMethodGrp);
+ myCreateRBtn = new QRadioButton(tr("CREATE_NEW_METHOD"), aMethodGrp);
+
+ // node ID
+
+ myNodeToMoveGrp = new QGroupBox(tr("NODE_2MOVE"), aFrame, "anIdGrp");
+
+ QLabel* idLabel = new QLabel(tr("NODE_2MOVE_ID"), myNodeToMoveGrp, "idLabel");
+ myIdBtn = new QPushButton(myNodeToMoveGrp);
+ myIdBtn->setPixmap(iconSelect);
+ myIdBtn->setToggleButton(TRUE);
+ myId = new QLineEdit(myNodeToMoveGrp,"myId");
+ myId->setValidator(new SMESHGUI_IdValidator(this, "validator", 1));
+ myAutoSearchChkBox = new QCheckBox( tr("AUTO_SEARCH"), myNodeToMoveGrp, "myAutoSearchChkBox");
+ myPreviewChkBox = new QCheckBox( tr("PREVIEW"), myNodeToMoveGrp, "myPreviewChkBox");
+
+ myNodeToMoveGrp->setColumnLayout(0, Qt::Vertical);
+ myNodeToMoveGrp->layout()->setSpacing(0);
+ myNodeToMoveGrp->layout()->setMargin(0);
+ QGridLayout* myNodeToMoveGrpLayout = new QGridLayout(myNodeToMoveGrp->layout());
+ myNodeToMoveGrpLayout->setAlignment(Qt::AlignTop);
+ myNodeToMoveGrpLayout->setSpacing(SPACING);
+ myNodeToMoveGrpLayout->setMargin(MARGIN);
+ myNodeToMoveGrpLayout->addWidget( idLabel, 0, 0 );
+ myNodeToMoveGrpLayout->addWidget( myIdBtn, 0, 1 );
+ myNodeToMoveGrpLayout->addWidget( myId, 0, 2 );
+ myNodeToMoveGrpLayout->addMultiCellWidget( myAutoSearchChkBox, 1, 1, 0, 2 );
+ myNodeToMoveGrpLayout->addMultiCellWidget( myPreviewChkBox, 2, 2, 0, 2 );
+
+ QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+ aLay->addWidget(aPixGrp);
+ aLay->addWidget(aCoordGrp);
+ aLay->addWidget(aMethodGrp);
+ aLay->addWidget(myNodeToMoveGrp);
+
+ connect(myCoordBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+ connect(myMoveRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+ connect(myCreateRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+ connect(myIdBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+ connect(myAutoSearchChkBox, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+
+ myMoveRBtn->setChecked(TRUE);
+ myIdBtn->setOn(TRUE);
+ myAutoSearchChkBox->setChecked(TRUE);
+
+ return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when any button is toggled
+ * \param bool - on or off
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointDlg::ButtonToggled (bool on)
+{
+ const QObject* aSender = sender();
+ if ( on ) {
+ if ( aSender == myCoordBtn ) // button to set coord by node selection
+ {
+ if ( myIdBtn->isEnabled() )
+ myIdBtn->setOn( !on );
+ }
+ else if ( aSender == myIdBtn ) // button to select a node to move
+ {
+ myCoordBtn->setOn( !on );
+ }
+ else if ( aSender == myMoveRBtn ) // move node method
+ {
+ myNodeToMoveGrp->setEnabled( TRUE );
+ }
+ else if ( aSender == myCreateRBtn ) // create node method
+ {
+ myNodeToMoveGrp->setEnabled( FALSE );
+ myCoordBtn->setOn( TRUE );
+ }
+ }
+ if ( aSender == myAutoSearchChkBox ) // automatic node search
+ {
+ if ( on ) {
+ myId->setText("");
+ myId->setReadOnly ( TRUE );
+ myIdBtn->setOn( FALSE );
+ myIdBtn->setEnabled( FALSE );
+ myCoordBtn->setOn( TRUE );
+ }
+ else {
+ myId->setReadOnly ( FALSE );
+ myIdBtn->setEnabled( TRUE );
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp()
+{
+ mySimulation = 0;
+ myDlg = new SMESHGUI_MakeNodeAtPointDlg;
+ myFilter = 0;
+
+ // connect signals and slots
+ connect(myDlg->myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+ connect(myDlg->myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+ connect(myDlg->myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+ connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
+ connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+ connect(myDlg->myAutoSearchChkBox,SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+ connect(myDlg->myMoveRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+ connect(myDlg->myCreateRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+void SMESHGUI_MakeNodeAtPointOp::startOperation()
+{
+ myNoPreview = false;
+ myMeshActor = 0;
+
+ // init simulation with a current View
+ if ( mySimulation ) delete mySimulation;
+ mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+ vtkProperty* aProp = vtkProperty::New();
+ aProp->SetRepresentationToWireframe();
+ aProp->SetColor(250, 0, 250);
+ aProp->SetPointSize(5);
+ aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1);
+ mySimulation->GetActor()->SetProperty(aProp);
+ aProp->Delete();
+
+ SMESHGUI_SelectionOp::startOperation();
+
+ // SalomeApp_TypeFilter depends on a current study
+ if ( myFilter ) delete myFilter;
+ QPtrList<SUIT_SelectionFilter> filters;
+ filters.append( new SalomeApp_TypeFilter((SalomeApp_Study*)study(), "SMESH" ));
+ TColStd_MapOfInteger vertexType;
+ vertexType.Add( TopAbs_VERTEX );
+ filters.append( new SMESH_NumberFilter("GEOM", TopAbs_VERTEX, 1, vertexType ));
+ myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+ activateSelection(); // set filters
+
+ myDlg->myX->SetValue(0);
+ myDlg->myY->SetValue(0);
+ myDlg->myZ->SetValue(0);
+ myDlg->myId->setText("");
+ myDlg->show();
+
+ onSelectionDone(); // init myMeshActor
+
+ if ( myMeshActor ) {
+// myMeshOldDisplayMode = myMeshActor->GetRepresentation();
+// myMeshActor->SetRepresentation( VTK_WIREFRAME );
+ myMeshActor->SetPointRepresentation(true);
+ SMESH::RepaintCurrentView();
+ redisplayPreview();
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::stopOperation()
+{
+ myNoPreview = true;
+ mySimulation->SetVisibility(false);
+ if ( myMeshActor ) {
+// myMeshActor->SetRepresentation( myMeshOldDisplayMode );
+ myMeshActor->SetPointRepresentation(false);
+ SMESH::RepaintCurrentView();
+ myMeshActor = 0;
+ }
+ selectionMgr()->removeFilter( myFilter );
+ SMESHGUI_SelectionOp::stopOperation();
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: move or create a node
+ */
+//================================================================================
+
+bool SMESHGUI_MakeNodeAtPointOp::onApply()
+{
+ if( isStudyLocked() )
+ return false;
+
+ if ( !myMeshActor ) {
+ SUIT_MessageBox::warn1( dlg(), tr( "SMESH_WRN_WARNING" ),
+ tr("INVALID_MESH"), tr( "SMESH_BUT_OK" ) );
+ dlg()->show();
+ return false;
+ }
+
+ if ( !isValid() ) { // node id is invalid
+ SUIT_MessageBox::warn1( dlg(), tr( "SMESH_WRN_WARNING" ),
+ tr("INVALID_ID"), tr( "SMESH_BUT_OK" ) );
+ dlg()->show();
+ return false;
+ }
+
+
+ try {
+ SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
+ if (aMesh->_is_nil()) {
+ QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
+ tr("SMESHG_NO_MESH"), QMessageBox::Ok);
+ return true;
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+ if (aMeshEditor->_is_nil())
+ return true;
+
+ int aResult = 0;
+ if ( myDlg->myCreateRBtn->isOn() )
+ {
+ aResult = aMeshEditor->AddNode(myDlg->myX->GetValue(),
+ myDlg->myY->GetValue(),
+ myDlg->myZ->GetValue());
+ }
+ else
+ {
+ int anId = myDlg->myId->text().toInt();
+ aResult = aMeshEditor->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
+ myDlg->myY->GetValue(),
+ myDlg->myZ->GetValue(),
+ anId);
+ }
+ if (aResult)
+ {
+ myDlg->myId->setText("");
+
+ SALOME_ListIO aList;
+ selectionMgr()->setSelectedObjects(aList,false);
+ aList.Append(myMeshActor->getIO());
+ selectionMgr()->setSelectedObjects(aList,false);
+ SMESH::UpdateView();
+ }
+ }
+ catch (const SALOME::SALOME_Exception& S_ex) {
+ SalomeApp_Tools::QtCatchCorbaException(S_ex);
+ }
+ catch (...) {
+ }
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Check selected node id validity
+ */
+//================================================================================
+
+bool SMESHGUI_MakeNodeAtPointOp::isValid()
+{
+ bool ok = true;
+
+ if ( myMeshActor &&
+ myDlg->myMoveRBtn->isOn() &&
+ !myDlg->myAutoSearchChkBox->isChecked() )
+ {
+ ok = false;
+ int id = myDlg->myId->text().toInt();
+ if ( id > 0 )
+ if (SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh())
+ ok = aMesh->FindNode( id );
+ }
+ return ok;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when selection changed
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
+{
+ if ( !myDlg->isShown() || !myDlg->isEnabled() )
+ return;
+ try {
+ SALOME_ListIO aList;
+ selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type());
+ if (aList.Extent() != 1)
+ return;
+ Handle(SALOME_InteractiveObject) anIO = aList.First();
+ SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
+
+ if (!aMeshActor) { // coord by geom
+ if ( myDlg->myCoordBtn->isOn() ) {
+ GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+ if ( !geom->_is_nil() ) {
+ TopoDS_Vertex aShape;
+ if ( GEOMBase::GetShape(geom, aShape) &&
+ aShape.ShapeType() == TopAbs_VERTEX ) {
+ gp_Pnt P = BRep_Tool::Pnt(aShape);
+ myNoPreview = true;
+ myDlg->myX->SetValue(P.X());
+ myDlg->myY->SetValue(P.Y());
+ myDlg->myZ->SetValue(P.Z());
+ myNoPreview = false;
+ redisplayPreview();
+ }
+ }
+ return;
+ }
+ }
+
+ if ( !myMeshActor )
+ myMeshActor = aMeshActor;
+
+ QString aString;
+ int nbElems = SMESH::GetNameOfSelectedElements(selector(),anIO, aString);
+ if (nbElems == 1) {
+ if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) {
+ if (const SMDS_MeshNode* aNode = aMesh->FindNode(aString.toInt())) {
+ myNoPreview = true;
+ if ( myDlg->myCoordBtn->isOn() ) { // set coord
+ myDlg->myX->SetValue(aNode->X());
+ myDlg->myY->SetValue(aNode->Y());
+ myDlg->myZ->SetValue(aNode->Z());
+ myNoPreview = false;
+ redisplayPreview();
+ }
+ else if ( myDlg->myIdBtn->isOn() &&
+ myDlg->myIdBtn->isEnabled() ) { // set node to move
+ myDlg->myId->setText(aString);
+ myNoPreview = false;
+ redisplayPreview();
+ }
+ }
+ }
+ }
+ } catch (...) {
+ }
+}
+
+//================================================================================
+/*!
+ * \brief update preview
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
+{
+ if ( myNoPreview )
+ return;
+ myNoPreview = true;
+
+ SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
+
+ bool moveShown = false;
+ if ( myDlg->myMoveRBtn->isOn() && // Move method
+ myMeshActor)
+ {
+ const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked();
+ const bool preview = myDlg->myPreviewChkBox->isChecked();
+ if ( autoSearch )
+ myDlg->myId->setText("");
+ if ( preview && ( autoSearch || isValid() ))
+ {
+ try {
+ SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
+ if (!aMesh->_is_nil()) {
+ SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer();
+ if (!aPreviewer->_is_nil())
+ {
+ SUIT_OverrideCursor aWaitCursor;
+
+ // find id and/or just compute preview
+ int anId = aPreviewer->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
+ myDlg->myY->GetValue(),
+ myDlg->myZ->GetValue(),
+ myDlg->myId->text().toInt());
+ if ( autoSearch ) { // set found id
+ QString idTxt("%1");
+ if ( anId > 0 )
+ idTxt = idTxt.arg( anId );
+ else
+ idTxt = "";
+ myDlg->myId->setText( idTxt );
+ }
+ if ( preview ) { // fill preview data
+ aMeshPreviewStruct = aPreviewer->GetPreviewData();
+ moveShown = ( anId > 0 );
+ }
+ }
+ }
+ }catch (...) {
+ }
+ }
+ }
+
+ if ( !moveShown )
+ {
+ aMeshPreviewStruct = new SMESH::MeshPreviewStruct();
+
+ aMeshPreviewStruct->nodesXYZ.length(1);
+ aMeshPreviewStruct->nodesXYZ[0].x = myDlg->myX->GetValue();
+ aMeshPreviewStruct->nodesXYZ[0].y = myDlg->myY->GetValue();
+ aMeshPreviewStruct->nodesXYZ[0].z = myDlg->myZ->GetValue();
+
+ aMeshPreviewStruct->elementTypes.length(1);
+ aMeshPreviewStruct->elementTypes[0].SMDS_ElementType = SMESH::NODE;
+ aMeshPreviewStruct->elementTypes[0].isPoly = false;
+ aMeshPreviewStruct->elementTypes[0].nbNodesInElement = 1;
+
+ aMeshPreviewStruct->elementConnectivities.length(1);
+ aMeshPreviewStruct->elementConnectivities[0] = 0;
+ }
+
+ // display data
+ if ( aMeshPreviewStruct.operator->() )
+ {
+ mySimulation->SetData(aMeshPreviewStruct._retn());
+ }
+ else
+{
+ mySimulation->SetVisibility(false);
+ }
+
+ myNoPreview = false;
+}
+
+//================================================================================
+/*!
+ * \brief Activate Node selection
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::activateSelection()
+{
+ selectionMgr()->clearFilters();
+ SMESH::SetPointRepresentation(false);
+ selectionMgr()->installFilter( myFilter );
+ setSelectionMode( NodeSelection );
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_MakeNodeAtPointOp::~SMESHGUI_MakeNodeAtPointOp()
+{
+ if ( myDlg ) delete myDlg;
+ if ( mySimulation ) delete mySimulation;
+ if ( myFilter ) delete myFilter;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_MakeNodeAtPointOp::dlg() const
+{
+ return myDlg;
+}
+
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_MakeNodeAtPointDlg.h
+// Author : Edward AGAPOV
+// Module : SMESH
+
+
+#ifndef SMESHGUI_MakeNodeAtPointDlg_H
+#define SMESHGUI_MakeNodeAtPointDlg_H
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+#include "VTKViewer.h"
+
+class QFrame;
+class QLineEdit;
+class QPushButton;
+class LightApp_SelectionMgr;
+class SVTK_ViewWindow;
+class QButtonGroup;
+class SMESHGUI;
+class QCheckBox;
+class QRadioButton;
+class SMESHGUI_SpinBox;
+class SALOME_Actor;
+class SMESHGUI_MeshEditPreview;
+class SMESHGUI_MakeNodeAtPointDlg;
+
+/*!
+ * \brief Operation to make a mesh pass through a point
+ */
+class SMESHGUI_MakeNodeAtPointOp: public SMESHGUI_SelectionOp
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_MakeNodeAtPointOp();
+ virtual ~SMESHGUI_MakeNodeAtPointOp();
+
+ virtual LightApp_Dialog* dlg() const;
+
+protected:
+
+ virtual void startOperation();
+ virtual void stopOperation();
+
+ virtual void activateSelection();
+
+ bool isValid();
+
+protected slots:
+ virtual bool onApply();
+
+private slots:
+
+ void onSelectionDone();
+ void redisplayPreview();
+
+private:
+
+ SMESHGUI_MakeNodeAtPointDlg* myDlg;
+
+ SUIT_SelectionFilter* myFilter;
+ int myMeshOldDisplayMode;
+ SMESHGUI_MeshEditPreview* mySimulation;
+ SMESH_Actor* myMeshActor;
+ bool myNoPreview;
+
+};
+
+/*!
+ * \brief Dialog to make a mesh pass through a point
+ */
+
+class SMESHGUI_MakeNodeAtPointDlg : public SMESHGUI_Dialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_MakeNodeAtPointDlg();
+
+private:
+
+ QFrame* createMainFrame (QWidget*);
+
+ QPushButton* myCoordBtn;
+ SMESHGUI_SpinBox *myX, *myY, *myZ;
+ QRadioButton *myMoveRBtn, *myCreateRBtn;
+ QGroupBox* myNodeToMoveGrp;
+ QPushButton* myIdBtn;
+ QLineEdit* myId;
+ QCheckBox* myAutoSearchChkBox;
+ QCheckBox* myPreviewChkBox;
+
+ QString myHelpFileName;
+
+ friend class SMESHGUI_MakeNodeAtPointOp;
+
+private slots:
+
+ void ButtonToggled (bool);
+};
+
+#endif
#include "SMESH_Actor.h"
#include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESHGUI_MeshUtils.h"
#include "SMDS_Mesh.hxx"
#include "GEOMBase.h"
#include <qpixmap.h>
#include <qheader.h>
+//IDL Headers
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
using namespace std;
//=================================================================================
// Controls for mesh defining
GroupMesh = new QGroupBox(this, "GroupMesh");
- GroupMesh->setTitle(tr("SMESH_MESH"));
+ GroupMesh->setTitle(tr("SMESH_SELECT_WHOLE_MESH"));
GroupMesh->setColumnLayout(0, Qt::Vertical);
GroupMesh->layout()->setSpacing(0);
GroupMesh->layout()->setMargin(0);
myEditCurrentArgument = (QWidget*)LineEditMesh;
myActor = 0;
+ mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
- myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+
+ // Costruction of the logical filter
+ SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+ SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP);
+
+ QPtrList<SUIT_SelectionFilter> aListOfFilters;
+ if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+ if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter);
+
+ myMeshOrSubMeshOrGroupFilter =
+ new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+
+ //myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
/* signals and slots connections */
connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
ListEdit->clear();
SMESH::array_of_long_array_var aNodeGroups;
- aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aNodeGroups);
+ if(!mySubMeshOrGroup->_is_nil())
+ aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aNodeGroups);
+ else
+ aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aNodeGroups);
for (int i = 0; i < aNodeGroups->length(); i++) {
SMESH::long_array& aGroup = aNodeGroups[i];
SMESH::SetPointRepresentation(false);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
- mySelectionMgr->installFilter(myMeshOrSubMeshFilter);
+ mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
}
myEditCurrentArgument->setFocus();
if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
QString aString = "";
LineEditMesh->setText(aString);
-
+
ListCoincident->clear();
ListEdit->clear();
-
+ myActor = 0;
+
int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
if (nbSel != 1)
return;
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
-
+
Handle(SALOME_InteractiveObject) IO = aList.First();
- myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
- myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
- if (myMesh->_is_nil() || !myActor)
+ myMesh = SMESH::GetMeshByIO(IO);
+
+ if (myMesh->_is_nil())
return;
-
+
+ myActor = SMESH::FindActorByEntry(IO->getEntry());
+ if (!myActor)
+ myActor = SMESH::FindActorByObject(myMesh);
+ if(!myActor)
+ return;
+
+ mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+
+ if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+ !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+ !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+ mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+
LineEditMesh->setText(aString);
}
}
// IDL Headers
#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
//=================================================================================
QWidget* myEditCurrentArgument;
SMESH::SMESH_Mesh_var myMesh;
+ SMESH::SMESH_IDSource_var mySubMeshOrGroup;
SMESH_Actor* myActor;
//Handle(SMESH_TypeFilter) myMeshOrSubMeshFilter;
- SUIT_SelectionFilter* myMeshOrSubMeshFilter;
+ SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
QButtonGroup* GroupConstructors;
QRadioButton* RadioButton1;
// Create tab widget
myTabWg = new QTabWidget( mainFrame() );
+ myTabs[ Dim0D ] = new SMESHGUI_MeshTab( myTabWg );
myTabs[ Dim1D ] = new SMESHGUI_MeshTab( myTabWg );
myTabs[ Dim2D ] = new SMESHGUI_MeshTab( myTabWg );
myTabs[ Dim3D ] = new SMESHGUI_MeshTab( myTabWg );
myTabWg->addTab( myTabs[ Dim3D ], tr( "DIM_3D" ) );
myTabWg->addTab( myTabs[ Dim2D ], tr( "DIM_2D" ) );
myTabWg->addTab( myTabs[ Dim1D ], tr( "DIM_1D" ) );
+ myTabWg->addTab( myTabs[ Dim0D ], tr( "DIM_0D" ) );
// Hypotheses Sets
myHypoSetPopup = new QPopupMenu();
//================================================================================
SMESHGUI_MeshTab* SMESHGUI_MeshDlg::tab( const int theId ) const
{
- return ( theId >= Dim1D && theId <= Dim3D ? myTabs[ theId ] : 0 );
+ return ( theId >= Dim0D && theId <= Dim3D ? myTabs[ theId ] : 0 );
}
//================================================================================
void SMESHGUI_MeshDlg::reset()
{
clearSelection();
+ myTabs[ Dim0D ]->reset();
myTabs[ Dim1D ]->reset();
myTabs[ Dim2D ]->reset();
myTabs[ Dim3D ]->reset();
void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim )
{
- const int DIM = maxDim - 1;
- for ( int dim = Dim1D; dim <= Dim3D; ++dim ) {
+ const int DIM = maxDim;
+ for ( int dim = Dim0D; dim <= Dim3D; ++dim ) {
bool enable = ( dim <= DIM );
if ( !enable )
myTabs[ dim ]->reset();
enum Controls { Obj, Mesh, Geom };
/*! Describes dimensions */
- enum Dimensions { Dim1D = 0, Dim2D, Dim3D };
+ enum Dimensions { Dim0D = 0, Dim1D, Dim2D, Dim3D };
public:
SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh );
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_MeshEditPreview.cxx
+// Module : SMESH
+// $Header:
+
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include "VTKViewer_CellLocationsArray.h"
+#include "SVTK_ViewWindow.h"
+
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESHGUI_VTKUtils.h"
+
+// VTK Includes
+#include <vtkPoints.h>
+#include <vtkIdList.h>
+#include <vtkCellArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkDataSetMapper.h>
+#include <vtkProperty.h>
+
+// QT Includes
+#include <qcolor.h>
+
+// IDL Headers
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+using namespace SMESH;
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_MeshEditPreview::SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindow):
+ myViewWindow(theViewWindow)
+{
+ myGrid = vtkUnstructuredGrid::New();
+
+ // Create and display actor
+ vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+ aMapper->SetInput( myGrid );
+
+ myPreviewActor = SALOME_Actor::New();
+ myPreviewActor->SetInfinitive(true);
+ myPreviewActor->VisibilityOn();
+ myPreviewActor->PickableOff();
+
+ vtkFloatingPointType anRGB[3];
+ GetColor( "SMESH", "selection_element_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+ SetColor( anRGB[0], anRGB[1], anRGB[2] );
+
+ myPreviewActor->SetMapper( aMapper );
+ aMapper->Delete();
+
+ myViewWindow->AddActor(myPreviewActor);
+
+}
+
+//================================================================================
+/*!
+ * \brief Destroy
+ */
+//================================================================================
+
+SMESHGUI_MeshEditPreview::~SMESHGUI_MeshEditPreview()
+{
+ myGrid->Delete();
+
+ myViewWindow->RemoveActor(myPreviewActor);
+ myPreviewActor->Delete();
+
+}
+
+//================================================================================
+/*!
+ * \brief Returns vtk cell type
+ */
+//================================================================================
+
+vtkIdType getCellType( const SMDSAbs_ElementType theType,
+ const bool thePoly,
+ const int theNbNodes )
+{
+ switch( theType )
+ {
+ case SMDSAbs_Node: return VTK_VERTEX;
+ case SMDSAbs_Edge:
+ if( theNbNodes == 2 ) return VTK_LINE;
+ else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE;
+ else return VTK_EMPTY_CELL;
+
+ case SMDSAbs_Face :
+ if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
+ else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
+ else if ( theNbNodes == 4 ) return VTK_QUAD;
+ else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE;
+ else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD;
+ else return VTK_EMPTY_CELL;
+
+ case SMDSAbs_Volume:
+ if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
+ else if ( theNbNodes == 4 ) return VTK_TETRA;
+ else if ( theNbNodes == 5 ) return VTK_PYRAMID;
+ else if ( theNbNodes == 6 ) return VTK_WEDGE;
+ else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
+ else if ( theNbNodes == 10 ) {
+ return VTK_QUADRATIC_TETRA;
+ }
+ else if ( theNbNodes == 20 ) {
+ return VTK_QUADRATIC_HEXAHEDRON;
+ }
+ else if ( theNbNodes==13 || theNbNodes==15 ) {
+ return VTK_CONVEX_POINT_SET;
+ }
+ else return VTK_EMPTY_CELL;
+
+ default: return VTK_EMPTY_CELL;
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Set preview data
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetData (const SMESH::MeshPreviewStruct* previewData)
+{
+ // Create points
+ const SMESH::nodes_array& aNodesXYZ = previewData->nodesXYZ;
+ vtkPoints* aPoints = vtkPoints::New();
+ aPoints->SetNumberOfPoints(aNodesXYZ.length());
+
+ for ( int i = 0; i < aNodesXYZ.length(); i++ ) {
+ aPoints->SetPoint( i, aNodesXYZ[i].x, aNodesXYZ[i].y, aNodesXYZ[i].z );
+ }
+ myGrid->SetPoints(aPoints);
+
+ aPoints->Delete();
+
+ // Create cells
+ const SMESH::long_array& anElemConnectivity = previewData->elementConnectivities;
+ const SMESH::types_array& anElemTypes = previewData->elementTypes;
+
+ vtkIdType aCellsSize = anElemConnectivity.length() + anElemTypes.length();
+ vtkIdType aNbCells = anElemTypes.length();
+
+ vtkCellArray* aConnectivity = vtkCellArray::New();
+ aConnectivity->Allocate( aCellsSize, 0 );
+
+ vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+ aCellTypesArray->SetNumberOfComponents( 1 );
+ aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
+
+ vtkIdList *anIdList = vtkIdList::New();
+ int aNodePos = 0;
+
+ for ( int i = 0; i < anElemTypes.length(); i++ ) {
+ const ElementSubType& anElementSubType = anElemTypes[i];
+ SMDSAbs_ElementType aType = SMDSAbs_ElementType(anElementSubType.SMDS_ElementType);
+ vtkIdType aNbNodes = anElementSubType.nbNodesInElement;
+ anIdList->SetNumberOfIds( aNbNodes );
+
+ for ( vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++ ){
+ anIdList->SetId( aNodeId, anElemConnectivity[aNodePos] );
+ aNodePos++;
+ }
+
+ aConnectivity->InsertNextCell( anIdList );
+ aCellTypesArray->InsertNextValue( getCellType( aType,
+ anElemTypes[i].isPoly,
+ aNbNodes ) );
+ }
+ anIdList->Delete();
+
+ // Insert cells in grid
+ VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+ aCellLocationsArray->SetNumberOfComponents( 1 );
+ aCellLocationsArray->SetNumberOfTuples( aNbCells );
+
+ aConnectivity->InitTraversal();
+ for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
+ aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
+
+ myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aConnectivity );
+
+ myPreviewActor->GetMapper()->Update();
+
+ aCellTypesArray->Delete();
+ aCellLocationsArray->Delete();
+ aConnectivity->Delete();
+
+ SetVisibility(true);
+}
+
+//================================================================================
+/*!
+ * \brief Set visibility
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetVisibility (bool theVisibility)
+{
+ myPreviewActor->SetVisibility(theVisibility);
+ RepaintCurrentView();
+}
+
+//================================================================================
+/*!
+ * \brief Set preview color
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetColor(double R, double G, double B)
+{
+ myPreviewActor->SetColor( R, G, B );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESHGUI_MeshEditPreview.cxx
+// Module : SMESH
+// $Header:
+
+#ifndef SMESHGUI_MESHEDITPREVIEW_H
+#define SMESHGUI_MESHEDITPREVIEW_H
+
+class SVTK_ViewWindow;
+class vtkUnstructuredGrid;
+class SALOME_Actor;
+namespace SMESH {
+ class MeshPreviewStruct;
+}
+
+/*!
+ * \brief Displayer of the mesh edition preview
+ */
+class SMESHGUI_MeshEditPreview {
+ SVTK_ViewWindow* myViewWindow;
+
+ vtkUnstructuredGrid* myGrid;
+ SALOME_Actor* myPreviewActor;
+
+public:
+
+ SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindow);
+ ~SMESHGUI_MeshEditPreview();
+
+ void SetData (const SMESH::MeshPreviewStruct* theMeshPreviewStruct);
+
+ void SetVisibility (bool theVisibility);
+
+ void SetColor(double R, double G, double B);
+
+ SALOME_Actor* GetActor() { return myPreviewActor; }
+
+};
+
+#endif
GLOBAL_HYPO_TAG =2,
LOCAL_ALGO_TAG =2,
LOCAL_HYPO_TAG =1,
+ SUBMESH_ON_VERTEX_TAG =4,
SUBMESH_ON_EDGE_TAG =5,
SUBMESH_ON_WIRE_TAG =6,
SUBMESH_ON_FACE_TAG =7,
if( !myDlg )
{
myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
- for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
+ for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
{
connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
this, SLOT( onCreateHyp( const int, const int ) ) );
}
SMESHGUI_SelectionOp::startOperation();
- // iterate through dimensions and get available algoritms,
- // set them to the dialog
+ // iterate through dimensions and get available algoritms, set them to the dialog
_PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
- for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
+ for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
{
SMESHGUI_MeshTab* aTab = myDlg->tab( i );
QStringList hypList;
GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
if (aSubGeomVar->_is_nil()) return false;
+ // skl for NPAL14695 - implementation of searching of mainObj
GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar);
- if (mainObj->_is_nil() ||
- string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
+ //if (mainObj->_is_nil() ||
+ // string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
+ while(1) {
+ if(mainObj->_is_nil())
+ return false;
+ if( string(mainObj->GetEntry()) == string(mainGeom->GetEntry()) )
+ return true;
+ mainObj = op->GetMainShape(mainObj);
+ }
}
- return true;
+ //return true;
}
return false;
if ( !geom->_is_nil() ) {
int tag = -1;
switch ( geom->GetShapeType() ) {
+ case GEOM::VERTEX: tag = SUBMESH_ON_VERTEX_TAG ; break;
case GEOM::EDGE: tag = SUBMESH_ON_EDGE_TAG ; break;
case GEOM::WIRE: tag = SUBMESH_ON_WIRE_TAG ; break;
case GEOM::FACE: tag = SUBMESH_ON_FACE_TAG ; break;
static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
{
int aDim = -1;
- for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++)
+ for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
if (tab == dlg->tab(i))
aDim = i;
return aDim;
const int theHypType,
const int theIndex)
{
- if ( theDim > -1 && theDim < 3 &&
+ if ( theDim > -1 && theDim <= SMESH::DIM_3D &&
theHypType > -1 && theHypType < NbHypTypes &&
theIndex > -1 && theIndex < myAvailableHypData[ theDim ][ theHypType ].count() )
return myAvailableHypData[ theDim ][ theHypType ][ theIndex ];
// find highest available dimension, all algos of this dimension are available for choice
int aTopDim = -1;
- for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++)
+ for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
if (isAccessibleDim( i ))
aTopDim = i;
if (aTopDim == -1)
const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
HypothesisData* algoData = hypData( aDim, Algo, theIndex );
- HypothesisData* algoByDim[3];
+ HypothesisData* algoByDim[4];
algoByDim[ aDim ] = algoData;
QStringList anAvailable;
{
int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
if ( !forward ) {
- dim = aDim - 1; lastDim = SMESH::DIM_1D; dir = -1;
+ dim = aDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
}
HypothesisData* prevAlgo = algoData;
bool noCompatible = false;
// restore previously selected algo
algoIndex = myAvailableHypData[dim][Algo].findIndex( curAlgo );
- if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward )
+ if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D)
// select the sole compatible algo
algoIndex = myAvailableHypData[dim][Algo].findIndex( soleCompatible );
setCurrentHyp( dim, Algo, algoIndex );
_PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
- for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
{
if ( !isAccessibleDim( dim ))
continue;
if (!aHypoSet) return;
// clear all hyps
- for (int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++) {
+ for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
setCurrentHyp(dim, Algo, -1);
setCurrentHyp(dim, AddHyp, -1);
setCurrentHyp(dim, MainHyp, -1);
if ( aMeshSO )
SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
- for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ ) {
+ for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
if ( !isAccessibleDim( aDim )) continue;
// assign hypotheses
// create sub-mesh
SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.latin1() );
- for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ )
+ for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
{
if ( !isAccessibleDim( aDim )) continue;
}
}
- // deselect geometry: next submesh sould be created on other subshape
- myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
+ // deselect geometry: next submesh should be created on other subshape
+ myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
selectObject( _PTR(SObject)() );
selectionDone();
// Get hypotheses and algorithms assigned to the mesh/sub-mesh
QStringList anExisting;
- for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
{
// get algorithm
existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
// get hypotheses
bool hypWithoutAlgo = false;
- for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
{
for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
{
// Set new name
SMESH::SetName( pObj, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
- // Assign new hypotheses and algorithms
- for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+ // First, remove old algos in order to avoid messages on algorithm hiding
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
+ {
+ if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 )
+ {
+ SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first();
+ SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
+ if ( anAlgoVar->_is_nil() || // no new algo selected or
+ strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) ) // algo change
+ {
+ // remove old algorithm
+ SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() );
+ myObjHyps[ dim ][ Algo ].clear();
+ }
+ }
+ }
+
+ // Assign new algorithms and hypotheses
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
{
if ( !isAccessibleDim( dim )) continue;
// find or create algorithm
- bool toDelete = false, toAdd = true;
SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
- if ( anAlgoVar->_is_nil() ) {
- toAdd = false;
- }
- if ( myObjHyps[ dim ][ Algo ].count() > 0 ) {
- SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first();
- if ( toAdd ) {
- if ( strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) == 0 ) {
- toAdd = false;
- } else {
- toDelete = true;
- }
- } else {
- toDelete = true;
- }
- }
- // remove old algorithm
- if ( toDelete ) {
- SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() );
- myObjHyps[ dim ][ Algo ].clear();
- }
// assign new algorithm
- if ( toAdd ) {
+ if ( !anAlgoVar->_is_nil() && // some algo selected and
+ myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
+ {
SMESH::SMESH_Mesh_var aMeshVar =
SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
bool isMesh = !aMeshVar->_is_nil();
// edited mesh/sub-mesh
// hypdata corresponding to hypotheses present in myDlg
- THypDataList myAvailableHypData[3][NbHypTypes];
+ THypDataList myAvailableHypData[4][NbHypTypes];
bool myIgnoreAlgoSelection;
};
// IDL Headers
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
#define MARGIN 10
#define SPACING 5
myId->setValidator(new SMESHGUI_IdValidator(this, "validator", 1));
QGroupBox* aCoordGrp = new QGroupBox(1, Qt::Vertical, tr("SMESH_COORDINATES"), aFrame);
- new QLabel(tr("SMESH_X"), aCoordGrp);
+ QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
+ aXLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
myX = new SMESHGUI_SpinBox(aCoordGrp);
- new QLabel(tr("SMESH_Y"), aCoordGrp);
+
+ QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
+ aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
myY = new SMESHGUI_SpinBox(aCoordGrp);
- new QLabel(tr("SMESH_Z"), aCoordGrp);
+
+ QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
+ aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
myZ = new SMESHGUI_SpinBox(aCoordGrp);
myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, 3);
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
#include CORBA_SERVER_HEADER(SMESH_Filter)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
class SMESHGUI;
class SMESHGUI_FilterDlg;
#include <qvalidator.h>
#include <qevent.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
using namespace std;
GroupCoordinatesLayout->setSpacing(6);
GroupCoordinatesLayout->setMargin(11);
TextLabel_X = new QLabel(GroupCoordinates, "TextLabel_X");
+ TextLabel_X->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
TextLabel_X->setText(tr("SMESH_X" ));
GroupCoordinatesLayout->addWidget(TextLabel_X, 0, 0);
TextLabel_Y = new QLabel(GroupCoordinates, "TextLabel_Y");
+ TextLabel_Y->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabel_Y->setText(tr("SMESH_Y" ));
GroupCoordinatesLayout->addWidget(TextLabel_Y, 0, 2);
TextLabel_Z = new QLabel(GroupCoordinates, "TextLabel_Z");
+ TextLabel_Z->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabel_Z->setText(tr("SMESH_Z" ));
GroupCoordinatesLayout->addWidget(TextLabel_Z, 0, 4);
using namespace std;
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
//=================================================================================
// class : SMESHGUI_RemoveElementsDlg()
// purpose :
using namespace std;
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
//=================================================================================
// class : SMESHGUI_RemoveNodesDlg()
// purpose :
using namespace std;
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
//=================================================================================
// class : SMESHGUI_RenumberingDlg()
// purpose :
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
GroupAxisLayout->addWidget(SelectPointButton, 0, 1);
TextLabelX = new QLabel(GroupAxis, "TextLabelX");
+ TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelX->setText(tr("SMESH_X"));
GroupAxisLayout->addWidget(TextLabelX, 0, 2);
GroupAxisLayout->addWidget(SpinBox_X, 0, 3);
TextLabelY = new QLabel(GroupAxis, "TextLabelY");
+ TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelY->setText(tr("SMESH_Y"));
GroupAxisLayout->addWidget(TextLabelY, 0, 4);
GroupAxisLayout->addWidget(SpinBox_Y, 0, 5);
TextLabelZ = new QLabel(GroupAxis, "TextLabelZ");
+ TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelZ->setText(tr("SMESH_Z"));
GroupAxisLayout->addWidget(TextLabelZ, 0, 6);
GroupAxisLayout->addWidget(SelectVectorButton, 1, 1);
TextLabelDX = new QLabel(GroupAxis, "TextLabelDX");
+ TextLabelDX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDX->setText(tr("SMESH_DX"));
GroupAxisLayout->addWidget(TextLabelDX, 1, 2);
GroupAxisLayout->addWidget(SpinBox_DX, 1, 3);
TextLabelDY = new QLabel(GroupAxis, "TextLabelDY");
+ TextLabelDY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDY->setText(tr("SMESH_DY"));
GroupAxisLayout->addWidget(TextLabelDY, 1, 4);
GroupAxisLayout->addWidget(SpinBox_DY, 1, 5);
TextLabelDZ = new QLabel(GroupAxis, "TextLabelDZ");
+ TextLabelDZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDZ->setText(tr("SMESH_DZ"));
GroupAxisLayout->addWidget(TextLabelDZ, 1, 6);
aNbUnits = anElementsIds->length();
}
} else {
- aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
myElementsId = aString;
}
myNbOkElements = true;
} else {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
if (aNbUnits != 1)
return;
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
GroupAxisLayout->addWidget(SelectPointButton, 0, 1);
TextLabelX = new QLabel(GroupAxis, "TextLabelX");
+ TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelX->setText(tr("SMESH_X"));
GroupAxisLayout->addWidget(TextLabelX, 0, 2);
GroupAxisLayout->addWidget(SpinBox_X, 0, 3);
TextLabelY = new QLabel(GroupAxis, "TextLabelY");
+ TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelY->setText(tr("SMESH_Y"));
GroupAxisLayout->addWidget(TextLabelY, 0, 4);
GroupAxisLayout->addWidget(SpinBox_Y, 0, 5);
TextLabelZ = new QLabel(GroupAxis, "TextLabelZ");
+ TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelZ->setText(tr("SMESH_Z"));
GroupAxisLayout->addWidget(TextLabelZ, 0, 6);
GroupAxisLayout->addWidget(SelectVectorButton, 1, 1);
TextLabelDX = new QLabel(GroupAxis, "TextLabelDX");
+ TextLabelDX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDX->setText(tr("SMESH_DX"));
GroupAxisLayout->addWidget(TextLabelDX, 1, 2);
GroupAxisLayout->addWidget(SpinBox_DX, 1, 3);
TextLabelDY = new QLabel(GroupAxis, "TextLabelDY");
+ TextLabelDY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDY->setText(tr("SMESH_DY"));
GroupAxisLayout->addWidget(TextLabelDY, 1, 4);
GroupAxisLayout->addWidget(SpinBox_DY, 1, 5);
TextLabelDZ = new QLabel(GroupAxis, "TextLabelDZ");
+ TextLabelDZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelDZ->setText(tr("SMESH_DZ"));
GroupAxisLayout->addWidget(TextLabelDZ, 1, 6);
aNbUnits = anElementsIds->length();
}
} else {
- aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
myElementsId = aString;
}
myNbOkElements = true;
} else {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
if (aNbUnits != 1)
return;
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
#include "SMESH_Actor.h"
#include <qlayout.h>
#include <qpixmap.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
using namespace std;
+
//=================================================================================
// class : SMESHGUI_SewingDlg()
// purpose :
return;
Handle(SALOME_InteractiveObject) IO = aList.First();
- myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+ myMesh = SMESH::GetMeshByIO(IO); //@ SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
if (myMesh->_is_nil() || !myActor)
if (GetConstructorId() != 3 ||
(myEditCurrentArgument != LineEdit1 && myEditCurrentArgument != LineEdit4)) {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
if (aNbUnits != 1)
return;
} else {
- aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
if (aNbUnits < 1)
return;
}
//================================================================================
/*!
* \brief Constructor
- * \param theToCreate - if this parameter is true then operation is used for creation,
- * for editing otherwise
- *
- * Initialize operation
*/
//================================================================================
SMESHGUI_ShapeByMeshOp::SMESHGUI_ShapeByMeshOp(bool isMultipleAllowed):
private:
-// void closeEvent (QCloseEvent* e);
-// void enterEvent (QEvent*);
-
-private:
-
- //QFrame* createButtonFrame (QWidget*);
QFrame* createMainFrame (QWidget*);
- //void displayPreview();
- //void erasePreview();
-private:
QButtonGroup* myElemTypeGroup;
QLineEdit* myElementId;
QLineEdit* myGeomName;
-private:
bool myIsMultipleAllowed;
void setMultipleAllowed(bool isAllowed) {myIsMultipleAllowed = isAllowed;};
-// QPushButton* myOkBtn;
-// QPushButton* myCloseBtn;
-
-// SMESHGUI* mySMESHGUI;
-// LightApp_SelectionMgr* mySelectionMgr;
-// SVTK_ViewWindow* myViewWindow;
-
friend class SMESHGUI_ShapeByMeshOp;
};
+/*!
+ * \brief Operation to publish a sub-shape of the mesh main shape
+ * by selecting mesh elements
+ */
class SMESHGUI_ShapeByMeshOp: public SMESHGUI_SelectionOp
{
Q_OBJECT
virtual void commitOperation();
virtual void startOperation();
- //virtual void selectionDone();
- //virtual SUIT_SelectionFilter* createFilter( const int ) const;
- //virtual bool isValid( SUIT_Operation* ) const;
void activateSelection();
void setElementID(const QString&);
-/* signals: */
-
-/* void PublishShape(); */
-/* void Close(); */
-
protected slots:
virtual bool onApply() { return true; }
-/* void onCreateHyp( const int theHypType, const int theIndex ); */
-/* void onEditHyp( const int theHypType, const int theIndex ); */
-/* void onHypoSet( const QString& theSetName ); */
-/* void onGeomSelectionByMesh( bool ); */
-/* void onPublishShapeByMeshDlg(); */
-/* void onCloseShapeByMeshDlg(); */
private slots:
-// void onOk();
-// void onClose();
-
-// void onDeactivate();
-
void onSelectionDone();
void onTypeChanged (int);
void onElemIdChanged (const QString&);
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
class QCloseEvent;
class QFrame;
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
aNbUnits = anElementsIds->length();
}
} else {
- aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
myElementsId = aString;
}
} else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myActor) {
myNbOkNodes = 0;
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
} else {
}
//================================================================================
void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
- const bool theIsComputed)
+ const bool theIsComputed,
+ const bool isEmpty)
{
class TEvent: public SALOME_Event
{
SALOMEDS::Study_var myStudy;
std::string myMeshEntry;
- bool myIsComputed;
+ bool myIsComputed, myIsEmpty;
public:
TEvent(const SALOMEDS::Study_var& theStudy,
const std::string& theMeshEntry,
- const bool theIsComputed):
+ const bool theIsComputed,
+ const bool isEmpty):
myStudy(theStudy),
myMeshEntry(theMeshEntry),
- myIsComputed(theIsComputed)
+ myIsComputed(theIsComputed),
+ myIsEmpty(isEmpty)
{}
virtual
SALOMEDS::SObject_var aMeshSO = myStudy->FindObjectID(myMeshEntry.c_str());
if(!aMeshSO->_is_nil())
if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO))
- SMESH::ModifiedMesh(aMesh,myIsComputed);
+ SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty);
}
};
ProcessVoidEvent(new TEvent(myStudy,
theMeshEntry,
- theIsComputed));
+ theIsComputed,
+ isEmpty));
}
* \param Mesh_Entry - entry of a mesh
* \param isComputed - is mesh computed or not
*/
- void SetMeshIcon(const char* Mesh_Entry, const bool isComputed);
+ void SetMeshIcon(const char* Mesh_Entry, const bool isComputed, const bool isEmpty);
private:
SALOMEDS::Study_var myStudy;
void SetName(const char* Entry, const char* Name);
- void SetMeshIcon(const char* Mesh_Entry, const bool isComputed);
+ void SetMeshIcon(const char* Mesh_Entry, const bool isComputed, const bool isEmpty);
void CreateAndDisplayActor( const char* Mesh_Entry );
};
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
GroupMirrorLayout->addWidget(SelectPointButton, 0, 1);
TextLabelX = new QLabel(GroupMirror, "TextLabelX");
+ TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelX->setText(tr("SMESH_X"));
GroupMirrorLayout->addWidget(TextLabelX, 0, 2);
GroupMirrorLayout->addWidget(SpinBox_X, 0, 3);
TextLabelY = new QLabel(GroupMirror, "TextLabelY");
+ TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelY->setText(tr("SMESH_Y"));
GroupMirrorLayout->addWidget(TextLabelY, 0, 4);
GroupMirrorLayout->addWidget(SpinBox_Y, 0, 5);
TextLabelZ = new QLabel(GroupMirror, "TextLabelZ");
+ TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabelZ->setText(tr("SMESH_Z"));
GroupMirrorLayout->addWidget(TextLabelZ, 0, 6);
aNbUnits = anElementsIds->length();
}
} else {
- aNbUnits = SMESH::GetNameOfSelectedElements( mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedElements( mySelector, IO, aString);
myElementsId = aString;
}
myNbOkElements = true;
} else {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
if (aNbUnits != 1)
return;
// IDL Headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
using namespace std;
GroupArgumentsLayout->addWidget(SelectButton1, 2, 1);
TextLabel1_1 = new QLabel(GroupArguments, "TextLabel1_1");
+ TextLabel1_1->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
GroupArgumentsLayout->addWidget(TextLabel1_1, 2, 2);
SpinBox1_1 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_1");
GroupArgumentsLayout->addWidget(SpinBox1_1, 2, 3);
TextLabel1_2 = new QLabel(GroupArguments, "TextLabel1_2");
+ TextLabel1_2->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
GroupArgumentsLayout->addWidget(TextLabel1_2, 2, 4);
SpinBox1_2 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_2");
GroupArgumentsLayout->addWidget(SpinBox1_2, 2, 5);
TextLabel1_3 = new QLabel(GroupArguments, "TextLabel1_3");
+ TextLabel1_3->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
GroupArgumentsLayout->addWidget(TextLabel1_3, 2, 6);
SpinBox1_3 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_3");
GroupArgumentsLayout->addWidget(SelectButton2, 3, 1);
TextLabel2_1 = new QLabel(GroupArguments, "TextLabel2_1");
+ TextLabel2_1->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabel2_1->setText(tr("SMESH_X" ));
GroupArgumentsLayout->addWidget(TextLabel2_1, 3, 2);
GroupArgumentsLayout->addWidget(SpinBox2_1, 3, 3);
TextLabel2_2 = new QLabel(GroupArguments, "TextLabel2_2");
+ TextLabel2_2->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabel2_2->setText(tr("SMESH_Y" ));
GroupArgumentsLayout->addWidget(TextLabel2_2, 3, 4);
GroupArgumentsLayout->addWidget(SpinBox2_2, 3, 5);
TextLabel2_3 = new QLabel(GroupArguments, "TextLabel2_3");
+ TextLabel2_3->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
TextLabel2_3->setText(tr("SMESH_Z"));
GroupArgumentsLayout->addWidget(TextLabel2_3, 3, 6);
myNbOkElements = true;
} else {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
if (aNbUnits != 1)
return;
#include <qstring.h>
#include "SMESHGUI_Utils.h"
+#include "SMESHGUI.h"
#include "OB_Browser.h"
#include "SUIT_Desktop.h"
#include "SUIT_Application.h"
#include "SUIT_Session.h"
+#include "SUIT_MessageBox.h"
#include "LightApp_SelectionMgr.h"
#include "SalomeApp_Application.h"
return theSObject->GetFather();
}
- void ModifiedMesh (_PTR(SObject) theSObject, bool theIsRight)
+ void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
{
_PTR(Study) aStudy = GetActiveStudyDocument();
if (aStudy->GetProperties()->IsLocked())
_PTR(GenericAttribute) anAttr =
aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap");
_PTR(AttributePixMap) aPixmap = anAttr;
- if (theIsRight) {
+ if (theIsNotModif) {
aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
- } else {
+ } else if ( isEmptyMesh ) {
aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
+ } else {
+ aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
}
_PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
_PTR(SObject) aSObj1 = anIter1->Value();
anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
aPixmap = anAttr;
- if (theIsRight) {
- aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
- } else {
- aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
- }
+ if (theIsNotModif) {
+ aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
+ } else if ( isEmptyMesh ) {
+ aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
+ } else {
+ aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
+ }
}
}
}
}
+ void ShowHelpFile (QString theHelpFileName)
+ {
+ LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+ if (app) {
+ SMESHGUI* gui = SMESHGUI::GetSMESHGUI();
+ app->onHelpContextModule(gui ? app->moduleName(gui->moduleName()) : QString(""),
+ theHelpFileName);
+ }
+ else {
+ SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
+ QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+ arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(theHelpFileName),
+ QObject::tr("BUT_OK"));
+ }
+ }
+
// void UpdateObjBrowser (bool)
// {
// //SMESHGUI::activeStudy()->updateObjBrowser(true);
_PTR(SObject) GetMeshOrSubmesh (_PTR(SObject) theSObject);
SMESHGUI_EXPORT
- void ModifiedMesh (_PTR(SObject) theSObject, bool theIsRight);
+ void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNot, bool isEmptyMesh=false);
-// void UpdateObjBrowser (bool);
+SMESHGUI_EXPORT
+ void ShowHelpFile (QString theHelpFileName);
}
#endif
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_Filter.h"
-#include <vtkRenderer.h>
-#include <vtkActorCollection.h>
-
-#include <TColStd_IndexedMapOfInteger.hxx>
+#include "SMESHGUI.h"
+#include "SMESH_Actor.h"
+#include "SMESH_ObjectDef.h"
#include <SUIT_Desktop.h>
#include <SUIT_Session.h>
#include <SUIT_Study.h>
-#include "LightApp_SelectionMgr.h"
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
-#include "SVTK_Selector.h"
-#include "SVTK_ViewModel.h"
-#include "SVTK_ViewWindow.h"
+#include <SVTK_Selector.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
-#include "utilities.h"
+#include <LightApp_SelectionMgr.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+
+#include <utilities.h>
-#include "SALOMEconfig.h"
+#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SMESH_Gen)
#include CORBA_CLIENT_HEADER(SMESH_Mesh)
#include CORBA_CLIENT_HEADER(SMESH_Group)
#include CORBA_CLIENT_HEADER(SMESH_Hypothesis)
-#include "SMESHGUI.h"
-#include "SMESH_Actor.h"
-#include "SMESH_ObjectDef.h"
-
-#include <SalomeApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-#include <SalomeApp_Study.h>
-
#include <SALOMEDSClient_Study.hxx>
#include <SALOMEDSClient_SObject.hxx>
-#include <SALOME_ListIO.hxx>
-#include <SALOME_ListIteratorOfListIO.hxx>
+// VTK
+#include <vtkRenderer.h>
+#include <vtkActorCollection.h>
+// OCCT
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+// STL
#include <set>
using namespace std;
-namespace SMESH{
+
+namespace SMESH {
typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
static TVisualObjCont VISUAL_OBJ_CONT;
if(anIter != VISUAL_OBJ_CONT.end()){
aVisualObj = anIter->second;
}else{
- SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
+ SalomeApp_Application* app =
+ dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
_PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
_PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
if(aSObj){
}
- SVTK_ViewWindow*
- GetViewWindow(const SalomeApp_Module* theModule)
+ /*! Return active view window, if it instantiates SVTK_ViewWindow class,
+ * overwise find or create corresponding view window, make it active and return it.
+ * \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
+ */
+ SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
+ bool createIfNotFound)
{
- if (SalomeApp_Application* anApp = theModule->getApp())
- return dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow());
+ SalomeApp_Application* anApp;
+ if (theModule)
+ anApp = theModule->getApp();
+ else
+ anApp = dynamic_cast<SalomeApp_Application*>
+ (SUIT_Session::session()->activeApplication());
+
+ if (anApp) {
+ if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
+ return aView;
+
+ SUIT_ViewManager* aViewManager =
+ anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
+ if (aViewManager) {
+ if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
+ if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
+ aViewWindow->raise();
+ aViewWindow->setFocus();
+ return aView;
+ }
+ }
+ }
+ }
return NULL;
}
- SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager* theMgr,
- SUIT_ViewWindow* theWindow )
+ SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
+ SUIT_ViewWindow * theWindow)
{
if( !theMgr )
return NULL;
return NULL;
}
-
SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
return dynamic_cast<SVTK_ViewWindow*>(theWindow);
}
-
/* SUIT_ViewWindow* GetActiveWindow()
{
SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
return GetVtkViewWindow( GetActiveWindow() );
}
+
+ void RepaintCurrentView()
+ {
+ if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
+ {
+ wnd->getRenderer()->Render();
+ wnd->Repaint(false);
+ }
+ }
+
void RepaintViewWindow(SVTK_ViewWindow* theWindow)
{
+ theWindow->getRenderer()->Render();
theWindow->Repaint();
}
theWindow->Repaint();
}
+ void FitAll(){
+ if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
+ wnd->onFitAll();
+ wnd->Repaint();
+ }
+ }
+
+
SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
const char* theEntry)
{
}
- void FitAll(){
- if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
- wnd->onFitAll();
- wnd->Repaint();
- }
- }
-
- vtkRenderer* GetCurrentRenderer(){
- if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
- return wnd->getRenderer();
- return NULL;
- }
-
- void RepaintCurrentView(){
- if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
- {
- wnd->getRenderer()->Render();
- wnd->Repaint(false);
- }
- }
-
void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
{
if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
// update VTK viewer properties
if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
// mesh element selection
- aVtkView->SetSelectionProp(aSelColor.red()/255.,
+ aVtkView->SetSelectionProp(aSelColor.red()/255.,
aSelColor.green()/255.,
- aSelColor.blue()/255.,
+ aSelColor.blue()/255.,
SW );
// tolerances
aVtkView->SetSelectionTolerance(SP1, SP2);
// pre-selection
- aVtkView->SetPreselectionProp(aPreColor.red()/255.,
+ aVtkView->SetPreselectionProp(aPreColor.red()/255.,
aPreColor.green()/255.,
- aPreColor.blue()/255.,
+ aPreColor.blue()/255.,
PW);
// update actors
vtkRenderer* aRenderer = aVtkView->getRenderer();
aCollection->InitTraversal();
while(vtkActor *anAct = aCollection->GetNextActor()){
if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
- anActor->SetHighlightColor(aHiColor.red()/255.,
+ anActor->SetHighlightColor(aHiColor.red()/255.,
aHiColor.green()/255.,
aHiColor.blue()/255.);
- anActor->SetPreHighlightColor(aPreColor.red()/255.,
+ anActor->SetPreHighlightColor(aPreColor.red()/255.,
aPreColor.green()/255.,
aPreColor.blue()/255.);
}
//----------------------------------------------------------------------------
- SVTK_Selector*
+ SVTK_Selector*
GetSelector(SUIT_ViewWindow *theWindow)
{
if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#ifndef SMESHGUI_VTKUtils_HeaderFile
#define SMESHGUI_VTKUtils_HeaderFile
#include "SMESH_SMESHGUI.hxx"
-class QString;
-class vtkRenderer;
-class TColStd_IndexedMapOfInteger;
-
#include "SALOMEDSClient_definitions.hxx"
#include "SALOME_InteractiveObject.hxx"
#include "VTKViewer_Filter.h"
+#include "SMESH_Object.h"
+#include "SMESHGUI_Utils.h"
+
+#include <CORBA.h>
+
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+
+#include <boost/shared_ptr.hpp>
+
+class QString;
+
+class TColStd_IndexedMapOfInteger;
+
class SALOMEDSClient_Study;
class SUIT_Study;
class SVTK_Selector;
class LightApp_SelectionMgr;
-class SMESHGUI;
-
-#include <omniORB4/CORBA.h>
-
-#include "SALOMEconfig.h"
-#include CORBA_CLIENT_HEADER(SALOMEDS)
-
-#include <boost/shared_ptr.hpp>
-#include "SMESH_Object.h"
+class SalomeApp_Module;
+class SMESHGUI;
class SMESH_Actor;
class SALOME_Actor;
-class SVTK_ViewWindow;
-class SalomeApp_Module;
-namespace SMESH{
+namespace SMESH {
//----------------------------------------------------------------------------
typedef pair<int,string> TKeyOfVisualObj;
//----------------------------------------------------------------------------
SMESHGUI_EXPORT
- SVTK_ViewWindow* GetViewWindow(const SalomeApp_Module* theModule);
-
-SMESHGUI_EXPORT
- SUIT_ViewWindow* GetActiveWindow();
-
+ SVTK_ViewWindow* GetViewWindow(const SalomeApp_Module* theModule = NULL,
+ bool createIfNotFound = false);
SMESHGUI_EXPORT
- SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager*,
- SUIT_ViewWindow* );
-
+ SVTK_ViewWindow* FindVtkViewWindow(SUIT_ViewManager*, SUIT_ViewWindow*);
SMESHGUI_EXPORT
- SVTK_ViewWindow* GetVtkViewWindow( SUIT_ViewWindow* );
+ SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow*);
SMESHGUI_EXPORT
SVTK_ViewWindow* GetCurrentVtkView();
+ //----------------------------------------------------------------------------
+SMESHGUI_EXPORT
+ void RepaintCurrentView();
SMESHGUI_EXPORT
void RepaintViewWindow(SVTK_ViewWindow*);
SMESHGUI_EXPORT
void RenderViewWindow(SVTK_ViewWindow*);
+SMESHGUI_EXPORT
+ void FitAll();
//----------------------------------------------------------------------------
SMESHGUI_EXPORT
//----------------------------------------------------------------------------
enum EDisplaing {eDisplayAll, eDisplay, eDisplayOnly, eErase, eEraseAll};
SMESHGUI_EXPORT
- void UpdateView (SUIT_ViewWindow*,
- EDisplaing theAction,
- const char* theEntry = "");
-SMESHGUI_EXPORT
- void UpdateView (EDisplaing theAction,
+ void UpdateView (SUIT_ViewWindow*,
+ EDisplaing theAction,
+ const char* theEntry = "" );
+SMESHGUI_EXPORT
+ void UpdateView (EDisplaing theAction,
const char* theEntry = "");
SMESHGUI_EXPORT
//----------------------------------------------------------------------------
-SMESHGUI_EXPORT
- void FitAll();
-
-SMESHGUI_EXPORT
- void RepaintCurrentView();
-
-SMESHGUI_EXPORT
- vtkRenderer* GetCurrentRenderer();
-
-
- //----------------------------------------------------------------------------
-SMESHGUI_EXPORT
+SMESHGUI_EXPORT
void SetPointRepresentation(bool theIsVisible);
SMESHGUI_EXPORT
//----------------------------------------------------------------------------
SMESHGUI_EXPORT
- SVTK_Selector*
- GetSelector(SUIT_ViewWindow* = GetActiveWindow());
+ SVTK_Selector* GetSelector (SUIT_ViewWindow* = GetActiveWindow());
SMESHGUI_EXPORT
void SetFilter (const Handle(VTKViewer_Filter)& theFilter,
SVTK_Selector* theSelector = GetSelector());
-
SMESHGUI_EXPORT
- Handle(VTKViewer_Filter)
- GetFilter (int theId, SVTK_Selector* theSelector = GetSelector());
-
+ Handle(VTKViewer_Filter) GetFilter (int theId, SVTK_Selector* theSelector = GetSelector());
SMESHGUI_EXPORT
- bool IsFilterPresent (int theId,
- SVTK_Selector* theSelector = GetSelector());
-
+ bool IsFilterPresent (int theId, SVTK_Selector* theSelector = GetSelector());
SMESHGUI_EXPORT
- void RemoveFilter (int theId,
- SVTK_Selector* theSelector = GetSelector());
+ void RemoveFilter (int theId, SVTK_Selector* theSelector = GetSelector());
SMESHGUI_EXPORT
void RemoveFilters (SVTK_Selector* theSelector = GetSelector());
SVTK_Selector* theSelector = GetSelector());
//----------------------------------------------------------------------------
-SMESHGUI_EXPORT
- int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
- const Handle(SALOME_InteractiveObject)& theIO,
+SMESHGUI_EXPORT
+ int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
+ const Handle(SALOME_InteractiveObject)& theIO,
QString& theName);
-
SMESHGUI_EXPORT
- int GetNameOfSelectedElements(SVTK_Selector* theSelector,
- const Handle(SALOME_InteractiveObject)& theIO,
+ int GetNameOfSelectedElements(SVTK_Selector* theSelector,
+ const Handle(SALOME_InteractiveObject)& theIO,
QString& theName);
-
SMESHGUI_EXPORT
- int GetEdgeNodes(SVTK_Selector* theSelector,
+ int GetEdgeNodes(SVTK_Selector* theSelector,
const TVisualObjPtr& theVisualObj,
- int& theId1,
+ int& theId1,
int& theId2);
//----------------------------------------------------------------------------
-SMESHGUI_EXPORT
- int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
- const Handle(SALOME_InteractiveObject)& theIO,
+SMESHGUI_EXPORT
+ int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
+ const Handle(SALOME_InteractiveObject)& theIO,
QString& theName);
-
SMESHGUI_EXPORT
- int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
+ int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
QString& aName);
-
SMESHGUI_EXPORT
- int GetNameOfSelectedElements (LightApp_SelectionMgr*,
- const Handle(SALOME_InteractiveObject)& theIO,
+ int GetNameOfSelectedElements (LightApp_SelectionMgr*,
+ const Handle(SALOME_InteractiveObject)& theIO,
QString& theName);
-
SMESHGUI_EXPORT
- int GetNameOfSelectedElements (LightApp_SelectionMgr*,
+ int GetNameOfSelectedElements (LightApp_SelectionMgr*,
QString& aName);
-
SMESHGUI_EXPORT
- int GetSelected (LightApp_SelectionMgr*,
- TColStd_IndexedMapOfInteger& theMap,
+ int GetSelected (LightApp_SelectionMgr*,
+ TColStd_IndexedMapOfInteger& theMap,
const bool theIsElement = true );
SMESHGUI_EXPORT
{
int aVal = (*anIter).toInt( &isOk );
if ( isOk )
- aDim.append( aVal - 1 );
+ aDim.append( aVal );
}
// for algo
}
}
- HypothesisData* aHypLibNames =
+ HypothesisData* aHypData =
new HypothesisData (aHypAlType, myPluginName, myServerLib, myClientLib,
aLabel, anIcon, aDim, isAux,
attr[ HYPOS ], attr[ OPT_HYPOS ], attr[ INPUT ], attr[ OUTPUT ]);
if (qName == "algorithm")
{
- myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+ myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypData;
}
else
{
- myHypothesesMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+ myHypothesesMap[(char*)aHypAlType.latin1()] = aHypData;
}
}
}
msgid "ICON_DLG_MOVE_NODE"
msgstr "mesh_move_node.png"
+#Mesh to pass through point
+msgid "ICON_DLG_MESH_THROU_POINT"
+msgstr "mesh_node_to_point.png"
+
#Remove Node
msgid "ICON_DLG_REM_NODE"
msgstr "mesh_rem_node.png"
msgid "ICON_DLG_MERGE_ELEMENTS"
msgstr "mesh_merge_elements.png"
+#Build compound
+msgid "ICON_DLG_BUILD_COMPOUND_MESH"
+msgstr "mesh_build_compound.png"
+
#-----------------------------------------------------------
# Hypothesis
#-----------------------------------------------------------
msgid "ICON_SMESH_TREE_MESH"
msgstr "mesh_tree_mesh.png"
+#mesh_tree_mesh
+msgid "ICON_SMESH_TREE_MESH_PARTIAL"
+msgstr "mesh_tree_mesh_partial.png"
+
#mesh_tree_group
msgid "ICON_SMESH_TREE_GROUP"
msgstr "mesh_tree_group.png"
msgid "ICON_COMPUTE"
msgstr "mesh_compute.png"
+msgid "ICON_BUILD_COMPOUND"
+msgstr "mesh_build_compound.png"
+
msgid "ICON_UNION"
msgstr "mesh_unionGroups.png"
msgstr "open.png"
msgid "ICON_CONV_TO_QUAD"
-msgstr "mesh_conv_to_quad.png"
\ No newline at end of file
+msgstr "mesh_conv_to_quad.png"
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2007-01-19 10:44+0300\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
# Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"PO-Revision-Date: 2006-01-13 13:50+0300\n"
+"PO-Revision-Date: 2006-12-28 12:10+0300\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
msgid "SMESH_WRN_COMPUTE_FAILED"
msgstr "Mesh computation failed"
+#Compute failed
+msgid "SMESH_COMPUTE_SUCCEED"
+msgstr "Mesh computation succeed"
+
#Study frame with VTK Viewer must be activated
msgid "SMESH_WRN_VIEWER_VTK"
msgstr "Study frame with VTK Viewer must be activated"
msgstr "Merge nodes"
#Merge elements
-msgid "SMESH_MERGE_ELEMENTS_TITLE"
+msgid "SMESH_MERGE_ELEMENTS"
msgstr "Merge elements"
#Extrusion
msgid "SMESH_ROTATION"
msgstr "Rotation"
+#Build compound
+msgid "SMESH_BUILD_COMPOUND_TITLE"
+msgstr "Create a Compound"
+
# -------------- Mesh Infos --------------
#Mesh Infos
msgid "SMESHGUI_FilterTable::BELONG_TO_CYLINDER"
msgstr "Belong to Cylinder"
+msgid "SMESHGUI_FilterTable::BELONG_TO_GENSURFACE"
+msgstr "Belong to Surface"
+
msgid "SMESHGUI_FilterTable::LYING_ON_GEOM"
msgstr "Lying on Geom"
msgid "SMESH_RM_HYP_WRN"
msgstr "\"%1\" unassigned but:\n"
+# Hypothesis_Status:
+
msgid "SMESH_HYP_1"
msgstr "Algorithm misses a hypothesis"
msgstr "Hypothesis has a bad parameter value"
msgid "SMESH_HYP_4"
-msgstr "Unknown fatal error at hypothesis definition"
+msgstr "Algorithm is hidden by an algorithm of upper dimension generating all-dimensions elements"
msgid "SMESH_HYP_5"
-msgstr "Hypothesis is not suitable in the current context"
+msgstr "Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements"
msgid "SMESH_HYP_6"
-msgstr "Non-conform mesh is produced using applied hypotheses"
+msgstr "Unknown fatal error at hypothesis definition"
msgid "SMESH_HYP_7"
-msgstr "Such dimention hypothesis is already assigned to the shape"
+msgstr "Hypothesis is not suitable in the current context"
msgid "SMESH_HYP_8"
-msgstr "Hypothesis and submesh dimensions mismatch"
+msgstr "Non-conform mesh is produced using applied hypotheses"
msgid "SMESH_HYP_9"
-msgstr "Shape is neither the main one, nor its subshape, nor a valid group"
+msgstr "Such dimention hypothesis is already assigned to the shape"
msgid "SMESH_HYP_10"
+msgstr "Hypothesis and submesh dimensions mismatch"
+
+msgid "SMESH_HYP_11"
+msgstr "Shape is neither the main one, nor its subshape, nor a valid group"
+
+msgid "SMESH_HYP_12"
msgstr "Geomerty mismatches algorithm's expectation"
-msgid "MISSING_ALGO"
+# SMESHGUI_HypothesesUtils::GetMessageOnAlgoStateErrors()
+# %1 - algo name
+# %2 - dimension
+# %3 - global/local
+# %4 - hypothesis dim == algoDim
+
+msgid "STATE_ALGO_MISSING"
msgstr "%3 %2D algorithm is missing"
-msgid "MISSING_HYPO"
+msgid "STATE_HYP_MISSING"
msgstr "%3 %2D algorithm \"%1\" misses %4D hypothesis"
-msgid "BAD_PARAM_VALUE"
+msgid "STATE_HYP_BAD_PARAMETER"
msgstr "Hypothesis of %3 %2D algorithm \"%1\" has a bad parameter value"
-msgid "NOT_CONFORM_MESH"
+msgid "STATE_HYP_NOTCONFORM"
msgstr "%3 %2D algorithm \"%1\" would produce not conform mesh: global \"Not Conform Mesh Allowed\" hypotesis is missing"
msgid "GLOBAL_ALGO"
msgstr "During export mesh with name - \"%1\" to UNV\n"
" pyramid's elements will be missed"
+msgid "SMESH_EXPORT_STL1"
+msgstr "Mesh - \"%1\" does not contain triangles"
+
+msgid "SMESH_EXPORT_STL2"
+msgstr "Mesh - \"%1\" contains another than triangles elements,"
+ " they are ignored during writing to STL"
+
msgid "SMESH_EXPORT_MED_DUPLICATED_GRP"
msgstr "There are duplicated group names in mesh \"%1\".\n"
"You can cancel exporting and rename them,\n"
msgid "SMESHGUI_CuttingOfQuadsDlg::CAPTION"
msgstr "Cutting of quadrangles"
-msgid "SMESHGUI_CuttingOfQuadsDlg::PREVIEW"
+msgid "PREVIEW"
msgstr "Preview"
#----------------------------------------------------
msgid "SMESHGUI_MoveNodesDlg::CAPTION"
msgstr "Move node"
-msgid "SMESHGUI_MoveNodesDlg::NODE_ID"
+msgid "NODE_ID"
msgstr "Node ID"
msgid "SMESHGUI_MoveNodesDlg::NODE_ID_IS_NOT_DEFINED"
#----------------------------------------------------
+msgid "SMESHGUI_MakeNodeAtPointDlg::CAPTION"
+msgstr "Mesh to pass through a point"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::MESH_PASS_THROUGH_POINT"
+msgstr "Make a node at point"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::METHOD"
+msgstr "Method"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::MOVE_EXISTING_METHOD"
+msgstr "Move a node"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::CREATE_NEW_METHOD"
+msgstr "Create a node"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::NODE_2MOVE"
+msgstr "Node to move"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::NODE_2MOVE_ID"
+msgstr "ID"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::AUTO_SEARCH"
+msgstr "Automatic search"
+
+msgid "SMESHGUI_MakeNodeAtPointOp::INVALID_ID"
+msgstr "Node ID is invalid"
+
+msgid "SMESHGUI_MakeNodeAtPointOp::INVALID_MESH"
+msgstr "Mesh to modify not selected"
+
+#----------------------------------------------------
+
msgid "SMESHGUI_DeleteGroupDlg::CAPTION"
msgstr "Delete groups with contents"
msgid "SMESHGUI_ExtrusionAlongPathDlg::SMESH_USE_ANGLES"
msgstr "Use Angles"
+msgid "SMESHGUI_ExtrusionAlongPathDlg::LINEAR_ANGLES"
+msgstr "Linear variation of the angles"
+
msgid "SMESHGUI_ExtrusionAlongPathDlg::SMESH_ANGLES"
msgstr "Rotation Angles"
msgid "SMESHGUI_RevolutionDlg::REVOLUTION_2D"
msgstr "Revolution of 2D elements"
+msgid "SMESHGUI_RevolutionDlg::ANGLE_BY_STEP"
+msgstr "Use Angle by Step"
+
+msgid "SMESHGUI_RevolutionDlg::TOTAL_ANGLE"
+msgstr "Use Total Angle"
+
+msgid "SMESHGUI_RevolutionDlg::PREVIEW"
+msgstr "Preview"
+
#----------------------------------------------------
#Coincident nodes
-msgid "SMESHGUI_MergeNodesDlg::COINCIDENT_NODES"
+msgid "SMESHGUI_EditMeshDlg::COINCIDENT_NODES"
msgstr "Coincident nodes"
+#Coincident elements
+msgid "SMESHGUI_EditMeshDlg::COINCIDENT_ELEMENTS"
+msgstr "Coincident elements"
+
#Detect
-msgid "SMESHGUI_MergeNodesDlg::DETECT"
+msgid "SMESHGUI_EditMeshDlg::DETECT"
msgstr "Detect"
#Select all
-msgid "SMESHGUI_MergeNodesDlg::SELECT_ALL"
+msgid "SMESHGUI_EditMeshDlg::SELECT_ALL"
msgstr "Select all"
-# Edit group of nodes
-msgid "SMESHGUI_MergeNodesDlg::EDIT_GROUP_OF_NODES"
-msgstr "Edit group of nodes"
+# Edit selected group
+msgid "SMESHGUI_EditMeshDlg::EDIT_SELECTED_GROUP"
+msgstr "Edit selected group"
#----------------------------------------------------
msgid "MEN_MED"
msgstr "MED file"
+msgid "MEN_STL"
+msgstr "STL file"
+
msgid "MEN_EXPORT_DAT"
msgstr "Export to DAT file"
msgid "MEN_EXPORT_MED"
msgstr "Export to MED file"
+msgid "MEN_EXPORT_STL"
+msgstr "Export to STL file"
+
msgid "MEN_DELETE"
msgstr "Delete"
msgid "MEN_CREATE_SUBMESH"
msgstr "Create Sub-mesh"
+msgid "MEN_BUILD_COMPOUND"
+msgstr "Build Compound"
+
msgid "MEN_GLOBAL_HYPO"
msgstr "Global Hypothesis"
msgid "MEN_MOVE"
msgstr "Move Node"
+msgid "MEN_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
msgid "MEN_INV"
msgstr "Diagonal Inversion"
msgid "TOP_EXPORT_MED"
msgstr "Export to MED file"
+msgid "TOP_EXPORT_STL"
+msgstr "Export to STL file"
+
msgid "TOP_DELETE"
msgstr "Delete"
msgid "TOP_CREATE_SUBMESH"
msgstr "Create Sub-mesh"
+msgid "TOP_BUILD_COMPOUND"
+msgstr "Build Compound Mesh"
+
msgid "TOP_GLOBAL_HYPO"
msgstr "Global Hypothesis"
msgid "TOP_MOVE"
msgstr "Move Node"
+msgid "TOP_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
msgid "TOP_INV"
msgstr "Diagonal Inversion"
msgid "STB_EXPORT_MED"
msgstr "Export to MED file"
+msgid "STB_EXPORT_STL"
+msgstr "Export to STL file"
+
msgid "STB_DELETE"
msgstr "Delete"
msgid "STB_CREATE_SUBMESH"
msgstr "Create Sub-mesh"
+msgid "STB_BUILD_COMPOUND"
+msgstr "Build Compound Mesh"
+
msgid "STB_GLOBAL_HYPO"
msgstr "Global Hypothesis"
msgid "STB_MOVE"
msgstr "Move Node"
+msgid "STB_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
msgid "STB_INV"
msgstr "Diagonal Inversion"
msgid "SMESHGUI::PREF_AUTO_GROUPS"
msgstr "Automatically create groups for MED export"
+msgid "SMESHGUI::PREF_RENUMBER"
+msgstr "Automatic renumbering"
+
#-----------------------------------------------------------
+msgid "SMESHGUI_MeshDlg::DIM_0D"
+msgstr "0D"
+
msgid "SMESHGUI_MeshDlg::DIM_1D"
msgstr "1D"
msgid "SMESHGUI_MeshDlg::HYPOTHESES_SETS"
msgstr "Assign a set of hypotheses"
+#-----------------------------------------------------------
+
+msgid "SMESHGUI_BuildCompoundDlg::COMPOUND"
+msgstr "Compound"
+
+msgid "SMESHGUI_BuildCompoundDlg::RESULT_NAME"
+msgstr "Result name"
+
+msgid "SMESHGUI_BuildCompoundDlg::COMPOUND_MESH"
+msgstr "Compound_Mesh"
+
+msgid "SMESHGUI_BuildCompoundDlg::MESHES"
+msgstr "Meshes"
+
+msgid "SMESHGUI_BuildCompoundDlg::PROCESSING_IDENTICAL_GROUPS"
+msgstr "Processing identical groups"
+
+msgid "SMESHGUI_BuildCompoundDlg::UNITE"
+msgstr "Unite"
+
+msgid "SMESHGUI_BuildCompoundDlg::RENAME"
+msgstr "Rename"
+
+msgid "SMESHGUI_BuildCompoundDlg::MERGE_NODES_AND_ELEMENTS"
+msgstr "Merge coincident nodes and elements"
#-----------------------------------------------------------
msgid "SMESHGUI_ConvToQuadOp::REF_IS_NULL"
msgstr "No valid mesh object selected"
+
+#-----------------------------------------------------------
+
+msgid "SMESHGUI_ComputeDlg::CAPTION"
+msgstr "Compute mesh failed"
+
+msgid "SMESHGUI_ComputeDlg::CONSTRUCTOR"
+msgstr "Compute mesh"
+
+msgid "SMESHGUI_ComputeDlg::ERRORS"
+msgstr "Errors"
+
+msgid "SMESHGUI_ComputeDlg::SHOW_SHAPE"
+msgstr "Show SubShape"
+
+msgid "SMESHGUI_ComputeDlg::PUBLISH_SHAPE"
+msgstr "Publish SubShape"
+
+msgid "COMPERR_OK"
+msgstr "No errors"
+
+msgid "COMPERR_BAD_INPUT_MESH"
+msgstr "Invalid input mesh"
+
+msgid "COMPERR_STD_EXCEPTION"
+msgstr "std::exception"
+
+msgid "COMPERR_OCC_EXCEPTION"
+msgstr "OCC exception"
+
+msgid "COMPERR_SLM_EXCEPTION"
+msgstr "SALOME exception"
+
+msgid "COMPERR_EXCEPTION"
+msgstr "Unknown exception"
+
+msgid "COMPERR_MEMORY_PB"
+msgstr "Memory allocation problem"
+
+msgid "COMPERR_ALGO_FAILED"
+msgstr "Algorithm failed"
+
+msgid "COMPERR_BAD_SHAPE"
+msgstr "Unexpected geometry"
+
+msgid "COL_ALGO_HEADER"
+msgstr "Algorithm"
+
+msgid "COL_SHAPE_HEADER"
+msgstr "SubShape"
+
+msgid "COL_ERROR_HEADER"
+msgstr "Error"
+
+#-----------------------------------------------------------
+
salomeinclude_HEADERS = \
SMESH_Gen_i.hxx \
SMESH_Algo_i.hxx \
- SMESH_1D_Algo_i.hxx \
+ SMESH_0D_Algo_i.hxx \
+ SMESH_1D_Algo_i.hxx \
SMESH_2D_Algo_i.hxx \
SMESH_3D_Algo_i.hxx \
SMESH_subMesh_i.hxx \
SMESH_MeshEditor_i.cxx \
SMESH_Hypothesis_i.cxx \
SMESH_Algo_i.cxx \
+ SMESH_0D_Algo_i.cxx \
SMESH_1D_Algo_i.cxx \
SMESH_2D_Algo_i.cxx \
SMESH_3D_Algo_i.cxx \
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_0D_Algo_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#include "SMESH_0D_Algo_i.hxx"
+
+//=============================================================================
+/*!
+ * SMESH_0D_Algo_i::SMESH_0D_Algo_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+SMESH_0D_Algo_i::SMESH_0D_Algo_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA )
+{
+}
+
+//=============================================================================
+/*!
+ * SMESH_0D_Algo_i::~SMESH_0D_Algo_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+SMESH_0D_Algo_i::~SMESH_0D_Algo_i()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether algorithm supports given entity type
+ * \param type - dimension (see SMESH::Dimension enumeration)
+ * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ *
+ * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================
+CORBA::Boolean SMESH_0D_Algo_i::IsDimSupported( SMESH::Dimension type )
+{
+ return type == SMESH::DIM_0D;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : SMESH_0D_Algo_i.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_0D_ALGO_I_HXX_
+#define _SMESH_0D_ALGO_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include "SMESH_Algo_i.hxx"
+
+// ======================================================
+// Generic 0D algorithm
+// ======================================================
+class SMESH_0D_Algo_i:
+ public virtual POA_SMESH::SMESH_0D_Algo,
+ public virtual SMESH_Algo_i
+{
+protected:
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_0D_Algo_i( PortableServer::POA_ptr thePOA );
+
+public:
+ // Destructor
+ virtual ~SMESH_0D_Algo_i();
+
+ // Verify whether algorithm supports given entity type
+ CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
using namespace std;
using SMESH::TPythonDump;
*/
//================================================================================
-void _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
+Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
{
// store theCommand in the sequence
myCommands.push_back( new _pyCommand( theCommand, ++myNbCommands ));
_pyID objID = aCommand->GetObject();
if ( objID.IsEmpty() )
- return;
+ return aCommand;
// SMESH_Gen method?
if ( objID == this->GetID() ) {
this->Process( aCommand );
- return;
+ return aCommand;
}
// SMESH_Mesh method?
map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
if ( id_mesh != myMeshes.end() ) {
id_mesh->second->Process( aCommand );
- return;
+ return aCommand;
}
// SMESH_Hypothesis method?
list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
for ( ; hyp != myHypos.end(); ++hyp )
if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
(*hyp)->Process( aCommand );
- return;
+ return aCommand;
}
// Add access to a wrapped mesh
AddMeshAccessorMethod( aCommand );
// Add access to a wrapped algorithm
- AddAlgoAccessorMethod( aCommand );
+ AddAlgoAccessorMethod( aCommand ); // ??? what if algo won't be wrapped at all ???
// PAL12227. PythonDump was not updated at proper time; result is
// aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
aCommand->GetString() += tmpCmd.GetString();
}
}
+ return aCommand;
}
//================================================================================
{
// there are methods to convert:
// CreateMesh( shape )
+ // Concatenate( [mesh1, ...], ... )
// CreateHypothesis( theHypType, theLibName )
// Compute( mesh, geom )
- if ( theCommand->GetMethod() == "CreateMesh" )
+ if ( theCommand->GetMethod() == "CreateMesh" ||
+ theCommand->GetMethod() == "CreateEmptyMesh" )
{
Handle(_pyMesh) mesh = new _pyMesh( theCommand );
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
// smeshgen.Method() --> smesh.smesh.Method()
theCommand->SetObject( SMESH_2smeshpy::GenName() );
+
+ // Concatenate( [mesh1, ...], ... )
+ if ( theCommand->GetMethod() == "Concatenate" )
+ {
+ AddMeshAccessorMethod( theCommand );
+ }
}
//================================================================================
//================================================================================
/*!
- * \brief Add access method to mesh that is object or arg
+ * \brief Add access method to mesh that is an object or an argument
* \param theCmd - command to add access method
* \retval bool - true if added
*/
bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
{
+ bool added = false;
map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
- return true;
+ added = true;
}
- return false;
+ return added;
}
//================================================================================
/*!
- * \brief Add access method to algo that is object or arg
+ * \brief Add access method to algo that is an object or an argument
* \param theCmd - command to add access method
* \retval bool - true if added
*/
bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
{
+ bool added = false;
list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
for ( ; hyp != myHypos.end(); ++hyp ) {
- if ( (*hyp)->IsAlgo() &&
+ if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
- return true;
+ added = true;
}
- return false;
+ return added;
}
//================================================================================
void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
{
-// cout << "SET\t" << theCmd->GetString() << endl << "AFTER\t" << theAfterCmd->GetString() << endl << endl;
+#ifdef _DEBUG_
+//cout << "SET\t" << theAfterCmd->GetString() << endl << "BEFORE\t" << theCmd->GetString() << endl<<endl;
+#endif
list< Handle(_pyCommand) >::iterator pos;
pos = find( myCommands.begin(), myCommands.end(), theCmd );
myCommands.erase( pos );
}
}
+namespace {
+
+ //================================================================================
+ /*!
+ * \brief add addition result treatement command
+ * \param addCmd - hypothesis addition command
+ */
+ //================================================================================
+
+ void addErrorTreatmentCmd( Handle(_pyCommand) & addCmd,
+ const bool isAlgo)
+ {
+ return; // TO DEBUD - TreatHypoStatus() is not placed right after addCmd
+ // addCmd: status = mesh.AddHypothesis( geom, hypo )
+ // treatement command:
+ // def TreatHypoStatus(status, hypName, geomName, isAlgo):
+ TCollection_AsciiString status = addCmd->GetResultValue();
+ if ( !status.IsEmpty() ) {
+ const _pyID& geomID = addCmd->GetArg( 1 );
+ const _pyID& hypoID = addCmd->GetArg( 2 );
+ TCollection_AsciiString cmdStr = addCmd->GetIndentation() +
+ SMESH_2smeshpy::SmeshpyName() + ".TreatHypoStatus( " + status + ", " +
+ SMESH_2smeshpy::SmeshpyName() + ".GetName(" + hypoID + "), " +
+ SMESH_2smeshpy::SmeshpyName() + ".GetName(" + geomID + "), " +
+ (char*)( isAlgo ? "True" : "False" ) + " )";
+ Handle(_pyCommand) cmd = theGen->AddCommand( cmdStr );
+ addCmd->AddDependantCmd( cmd, true );
+ }
+ }
+}
+
//================================================================================
/*!
* \brief Convert creation and addition of all algos and hypos
// mesh.GetMesh().AddHypothesis(geom, ALGO ) ->
// mesh.GetMesh().AddHypothesis(geom, ALGO.GetAlgorithm() )
addCmd->SetArg( 2, addCmd->GetArg( 2 ) + ".GetAlgorithm()" );
+ // add addition result treatement cmd
+ addErrorTreatmentCmd( addCmd, true );
}
}
Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
if ( hyp.IsNull() || hyp->IsAlgo() )
continue;
- const _pyID& geom = addCmd->GetArg( 1 );
- // find algo created on <geom> for this mesh
- Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, this->GetID(), hyp->GetType() );
- //_pyID algoID = algo.IsNull() ? "" : algo->GetID();
- if ( !algo.IsNull() && hyp->Addition2Creation( addCmd, this->GetID() )) // OK
- {
- addCmd->SetObject( algo->GetID() );
- algo->GetCreationCmd()->AddDependantCmd( addCmd );
- }
- else
+ if ( !hyp->Addition2Creation( addCmd, this->GetID() ))
{
AddMeshAccess( addCmd );
+ // add addition result treatement cmd
+ addErrorTreatmentCmd( addCmd, false );
}
}
_pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
_pyObject( theCreationCmd )
{
- myDim = myIsAlgo = /*myIsLocal = */myIsWrapped = myIsConverted = false;
+ myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
}
//================================================================================
// 1D Regular_1D ----------
if ( hypType == "Regular_1D" ) {
- algo->SetDimMethodType( 1, "Segment");
+ // set mesh's method creating algo,
+ // i.e. convertion result will be "regular1d = Mesh.Segment()",
+ // and set hypType by which algo creating a hypothesis is searched for
+ algo->SetConvMethodAndType("Segment", hypType.ToCString());
+ }
+ else if ( hypType == "CompositeSegment_1D" ) {
+ algo->SetConvMethodAndType("Segment", "Regular_1D");
+ algo->myArgs.Append( "algo=smesh.COMPOSITE");
}
else if ( hypType == "LocalLength" ) {
- hyp->SetDimMethodType( 1, "LocalLength", "Regular_1D");
+ // set algo's method creating hyp, and algo type
+ hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
+ // set method whose 1 arg will become the 1-st arg of hyp creation command
+ // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
hyp->AddArgMethod( "SetLength" );
}
else if ( hypType == "NumberOfSegments" ) {
hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
- hyp->SetDimMethodType( 1, "NumberOfSegments", "Regular_1D");
+ hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
+ // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
hyp->AddArgMethod( "SetNumberOfSegments" );
+ // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
hyp->AddArgMethod( "SetScaleFactor" );
}
else if ( hypType == "Arithmetic1D" ) {
hyp = new _pyComplexParamHypo( theCreationCmd );
- hyp->SetDimMethodType( 1, "Arithmetic1D", "Regular_1D");
+ hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
}
else if ( hypType == "StartEndLength" ) {
hyp = new _pyComplexParamHypo( theCreationCmd );
- hyp->SetDimMethodType( 1, "StartEndLength", "Regular_1D");
+ hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
}
else if ( hypType == "Deflection1D" ) {
- hyp->SetDimMethodType( 1, "Deflection1D", "Regular_1D");
+ hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
hyp->AddArgMethod( "SetDeflection" );
}
else if ( hypType == "Propagation" ) {
- hyp->SetDimMethodType( 1, "Propagation", "Regular_1D");
+ hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
}
else if ( hypType == "QuadraticMesh" ) {
- hyp->SetDimMethodType( 1, "QuadraticMesh", "Regular_1D");
+ hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
}
else if ( hypType == "AutomaticLength" ) {
- hyp->SetDimMethodType( 1, "AutomaticLength", "Regular_1D");
+ hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
hyp->AddArgMethod( "SetFineness");
}
+ else if ( hypType == "SegmentLengthAroundVertex" ) {
+ hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
+ hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
+ hyp->AddArgMethod( "SetLength" );
+ }
// 1D Python_1D ----------
else if ( hypType == "Python_1D" ) {
- algo->SetDimMethodType( 1, "Segment");
+ algo->SetConvMethodAndType( "Segment", hypType.ToCString());
algo->myArgs.Append( "algo=smesh.PYTHON");
}
else if ( hypType == "PythonSplit1D" ) {
- hyp->SetDimMethodType( 1, "PythonSplit1D", "Python_1D");
+ hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
hyp->AddArgMethod( "SetNumberOfSegments");
hyp->AddArgMethod( "SetPythonLog10RatioFunction");
}
// 2D ----------
else if ( hypType == "MEFISTO_2D" ) {
- algo->SetDimMethodType( 2, "Triangle");
+ algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
}
else if ( hypType == "MaxElementArea" ) {
- hyp->SetDimMethodType( 2, "MaxElementArea", "MEFISTO_2D");
+ hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
hyp->AddArgMethod( "SetMaxElementArea");
}
else if ( hypType == "LengthFromEdges" ) {
- hyp->SetDimMethodType( 2, "LengthFromEdges", "MEFISTO_2D");
+ hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
}
else if ( hypType == "Quadrangle_2D" ) {
- algo->SetDimMethodType( 2, "Quadrangle" );
+ algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
}
else if ( hypType == "QuadranglePreference" ) {
- hyp->SetDimMethodType( 2, "QuadranglePreference", "Quadrangle_2D");
+ hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
}
// 3D ----------
else if ( hypType == "NETGEN_3D") {
- algo->SetDimMethodType( 3, "Tetrahedron" );
+ algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
algo->myArgs.Append( "algo=smesh.NETGEN" );
}
else if ( hypType == "MaxElementVolume") {
- hyp->SetDimMethodType( 3, "MaxElementVolume", "NETGEN_3D");
+ hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
hyp->AddArgMethod( "SetMaxElementVolume" );
}
else if ( hypType == "GHS3D_3D" ) {
- algo->SetDimMethodType( 3, "Tetrahedron");
+ algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
algo->myArgs.Append( "algo=smesh.GHS3D" );
}
else if ( hypType == "Hexa_3D" ) {
- algo->SetDimMethodType( 3, "Hexahedron");
+ algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
}
// Repetitive ---------
else if ( hypType == "Projection_1D" ) {
- algo->SetDimMethodType( 1, "Projection1D");
+ algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
}
else if ( hypType == "ProjectionSource1D" ) {
- hyp->SetDimMethodType( 1, "SourceEdge", "Projection_1D");
+ hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
hyp->AddArgMethod( "SetSourceEdge");
hyp->AddArgMethod( "SetSourceMesh");
+ // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
hyp->AddArgMethod( "SetVertexAssociation", 2 );
}
else if ( hypType == "Projection_2D" ) {
- algo->SetDimMethodType( 2, "Projection2D");
+ algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
}
else if ( hypType == "ProjectionSource2D" ) {
- hyp->SetDimMethodType( 2, "SourceFace", "Projection_2D");
+ hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
hyp->AddArgMethod( "SetSourceFace");
hyp->AddArgMethod( "SetSourceMesh");
hyp->AddArgMethod( "SetVertexAssociation", 4 );
}
else if ( hypType == "Projection_3D" ) {
- algo->SetDimMethodType( 3, "Projection3D");
+ algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
}
else if ( hypType == "ProjectionSource3D" ) {
- hyp->SetDimMethodType( 3, "SourceShape3D", "Projection_3D");
+ hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
hyp->AddArgMethod( "SetSource3DShape");
hyp->AddArgMethod( "SetSourceMesh");
hyp->AddArgMethod( "SetVertexAssociation", 4 );
}
else if ( hypType == "Prism_3D" ) {
- algo->SetDimMethodType( 3, "Prism");
+ algo->SetConvMethodAndType( "Prism", hypType.ToCString());
}
else if ( hypType == "RadialPrism_3D" ) {
- algo->SetDimMethodType( 3, "Prism");
+ algo->SetConvMethodAndType( "Prism", hypType.ToCString());
}
else if ( hypType == "NumberOfLayers" ) {
- hyp->SetDimMethodType( 3, "NumberOfLayers", "RadialPrism_3D");
+ hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
hyp->AddArgMethod( "SetNumberOfLayers" );
}
else if ( hypType == "LayerDistribution" ) {
hyp = new _pyLayerDistributionHypo( theCreationCmd );
- hyp->SetDimMethodType( 3, "LayerDistribution", "RadialPrism_3D");
-// hyp->AddArgMethod( "SetSource3DShape");
-// hyp->AddArgMethod( "SetSourceMesh");
-// hyp->AddArgMethod( "SetVertexAssociation", 4 );
+ hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
}
- if ( algo->GetDim() ) {
- algo->myType = hypType;
+ if ( !algo->GetCreationMethod().IsEmpty() ) {
return algo;
}
return hyp;
if ( !IsWrappable( theMesh ))
return false;
- myIsWrapped = true;
+ myGeom = theCmd->GetArg( 1 );
- if ( myIsWrapped )
- {
- // mesh.AddHypothesis(geom,hyp) --> hyp = theMesh.myCreationMethod(args)
- theCmd->SetResultValue( GetID() );
- theCmd->SetObject( theMesh );
- theCmd->SetMethod( myCreationMethod );
- // set args
- theCmd->RemoveArgs();
- for ( int i = 1; i <= myArgs.Length(); ++i ) {
- if ( !myArgs( i ).IsEmpty() )
- theCmd->SetArg( i, myArgs( i ));
- else
- theCmd->SetArg( i, "[]");
- }
- // set a new creation command
- GetCreationCmd()->Clear();
- SetCreationCmd( theCmd );
-
- // clear commands setting arg values
- list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
- for ( ; argCmd != myArgCommands.end(); ++argCmd )
- (*argCmd)->Clear();
+ Handle(_pyHypothesis) algo;
+ if ( !IsAlgo() ) {
+ // find algo created on myGeom in theMesh
+ algo = theGen->FindAlgo( myGeom, theMesh, GetType() );
+ if ( algo.IsNull() )
+ return false;
+ algo->GetCreationCmd()->AddDependantCmd( theCmd );
}
- else
- {
-// // set arg commands after hypo creation
-// list<Handle(_pyCommand)>::iterator argCmd = myArgCommands.begin();
-// for ( ; argCmd != myArgCommands.end(); ++argCmd )
-// if ( !(*argCmd)->IsEmpty() && GetCommandNb() > (*argCmd)->GetOrderNb() )
-// theGen->ExchangeCommands( GetCreationCmd(), *argCmd );
+ myIsWrapped = true;
+
+ // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
+ theCmd->SetResultValue( GetID() );
+ theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
+ theCmd->SetMethod( myCreationMethod );
+ // set args
+ theCmd->RemoveArgs();
+ for ( int i = 1; i <= myArgs.Length(); ++i ) {
+ if ( !myArgs( i ).IsEmpty() )
+ theCmd->SetArg( i, myArgs( i ));
+ else
+ theCmd->SetArg( i, "[]");
}
+ // set a new creation command
+ GetCreationCmd()->Clear();
+ SetCreationCmd( theCmd );
+
+ // clear commands setting arg values
+ list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
+ for ( ; argCmd != myArgCommands.end(); ++argCmd )
+ (*argCmd)->Clear();
// set unknown arg commands after hypo creation
Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
}
}
+//================================================================================
+/*!
+ * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
+ * into regular1D.LengthNearVertex( length, vertex )
+ * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
+ * \param theMesh - The mesh needing this hypo
+ * \retval bool - false if the command cant be converted
+ */
+//================================================================================
+
+bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
+ const _pyID& theMeshID)
+{
+ if ( IsWrappable( theMeshID )) {
+
+ _pyID vertex = theCmd->GetArg( 1 );
+
+ // the problem here is that segment algo will not be found
+ // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
+ // geometry where segment algorithm is assigned
+ Handle(_pyHypothesis) algo;
+ _pyID geom = vertex;
+ while ( algo.IsNull() && !geom.IsEmpty()) {
+ // try to find geom as a father of <vertex>
+ geom = FatherID( geom );
+ algo = theGen->FindAlgo( geom, theMeshID, GetType() );
+ }
+ if ( algo.IsNull() )
+ return false; // also possible to find geom as brother of veretex...
+ // set geom instead of vertex
+ theCmd->SetArg( 1, geom );
+
+ // set vertex as a second arg
+ if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
+ myArgs.Append( vertex );
+
+ // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
+ // theMeshID.LengthNearVertex( length, vertex )
+ return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
+ }
+ return false;
+}
+
//================================================================================
/*!
* \brief _pyAlgorithm constructor
bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
const _pyID& theMeshID)
{
- if ( IsWrappable( theMeshID )) {
-
- myGeom = theCmd->GetArg( 1 );
-
- // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
- if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
- theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
- return true;
- }
+ // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
+ if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
+ theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
+ return true;
}
return false;
}
myBegPos( thePartIndex ) = thePosition;
}
+//================================================================================
+/*!
+ * \brief Returns whitespace symbols at the line beginning
+ * \retval TCollection_AsciiString - result
+ */
+//================================================================================
+
+TCollection_AsciiString _pyCommand::GetIndentation()
+{
+ int end = 1;
+ if ( GetBegPos( RESULT_IND ) == UNKNOWN )
+ GetWord( myString, end, true );
+ else
+ end = GetBegPos( RESULT_IND );
+ return myString.SubString( 1, end - 1 );
+}
+
//================================================================================
/*!
* \brief Return substring of python command looking like ResultValue = Obj.Meth()
int beg = GetBegPos( OBJECT_IND );
if ( beg < 1 || beg > Length() )
return false;
+ bool added = false;
while (( beg = myString.Location( theObjectID, beg, Length() )))
{
// check that theObjectID is not just a part of a longer ID
int afterEnd = beg + theObjectID.Length();
Standard_Character c = myString.Value( afterEnd );
if ( !isalnum( c ) && c != ':' ) {
- // insertion
- int oldLen = Length();
- myString.Insert( afterEnd, (char*) theAcsMethod );
- myString.Insert( afterEnd, "." );
- // update starting positions of the parts following the modified one
- int posDelta = Length() - oldLen;
- for ( int i = 1; i <= myBegPos.Length(); ++i ) {
- if ( myBegPos( i ) > afterEnd )
- myBegPos( i ) += posDelta;
+ // check if accessor method already present
+ if ( c != '.' ||
+ myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
+ // insertion
+ int oldLen = Length();
+ myString.Insert( afterEnd, (char*) theAcsMethod );
+ myString.Insert( afterEnd, "." );
+ // update starting positions of the parts following the modified one
+ int posDelta = Length() - oldLen;
+ for ( int i = 1; i <= myBegPos.Length(); ++i ) {
+ if ( myBegPos( i ) > afterEnd )
+ myBegPos( i ) += posDelta;
+ }
+ added = true;
}
- return true;
}
beg = afterEnd; // is a part - next search
}
- return false;
+ return added;
}
//================================================================================
{
return 0;
}
+//================================================================================
+/*!
+ * \brief Return ID of a father
+ */
+//================================================================================
+
+_pyID _pyObject::FatherID(const _pyID & childID)
+{
+ int colPos = childID.SearchFromEnd(':');
+ if ( colPos > 0 )
+ return childID.SubString( 1, colPos-1 );
+ return "";
+}
int Length() { return myString.Length(); }
void Clear() { myString.Clear(); myBegPos.Clear(); }
bool IsEmpty() const { return myString.IsEmpty(); }
+ TCollection_AsciiString GetIndentation();
const TCollection_AsciiString & GetResultValue();
const TCollection_AsciiString & GetObject();
const TCollection_AsciiString & GetMethod();
static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring,
int & theStartPos, const bool theForward,
const bool dotIsWord = false);
- void AddDependantCmd( Handle(_pyCommand) cmd)
- { return myDependentCmds.push_back( cmd ); }
+ void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false)
+ { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); }
bool SetDependentCmdsAfter() const;
bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
public:
_pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {}
const _pyID& GetID() { return myCreationCmd->GetResultValue(); }
+ static _pyID FatherID(const _pyID & childID);
const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
public:
_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod);
//~_pyGen();
- void AddCommand( const TCollection_AsciiString& theCommand );
+ Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
void Process( const Handle(_pyCommand)& theCommand );
void Flush();
Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
class _pyHypothesis: public _pyObject
{
protected:
- bool myIsAlgo, /*myIsLocal, */myIsWrapped, myIsConverted;
- int myDim/*, myAdditionCmdNb*/;
+ bool myIsAlgo, myIsWrapped; //myIsLocal, myIsConverted;
+ //int myDim/*, myAdditionCmdNb*/;
_pyID myGeom, myMesh;
TCollection_AsciiString myCreationMethod, myType;
TColStd_SequenceOfAsciiString myArgs;
std::list<Handle(_pyCommand)> myUnknownCommands;
public:
_pyHypothesis(const Handle(_pyCommand)& theCreationCmd);
- void SetDimMethodType(const int dim, const char* creationMethod, const char* type=0)
- { myDim = dim; myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
+ void SetConvMethodAndType(const char* creationMethod, const char* type=0)
+ { myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
+// void SetDimMethodType(const int dim, const char* creationMethod, const char* type=0)
+// { myDim = dim; myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
void AddArgMethod(const char* method, const int nbArgs = 1)
{ myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); }
const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
void ClearAllCommands();
virtual bool IsAlgo() const { return myIsAlgo; }
bool IsWrapped() const { return myIsWrapped; }
- bool & IsConverted() { return myIsConverted; }
- int GetDim() const { return myDim; }
+ //bool & IsConverted() { return myIsConverted; }
+ //int GetDim() const { return myDim; }
const _pyID & GetGeom() const { return myGeom; }
void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; }
const _pyID & GetMesh() const { return myMesh; }
DEFINE_STANDARD_RTTI (_pyHypothesis)
};
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief Class representing smesh.Mesh_Algorithm
+ */
+// -------------------------------------------------------------------------------------
+class _pyAlgorithm: public _pyHypothesis
+{
+public:
+ _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
+ virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
+ const _pyID& theMesh);
+ const char* AccessorMethod() const { return "GetAlgorithm()"; }
+
+ DEFINE_STANDARD_RTTI (_pyAlgorithm)
+};
+
// -------------------------------------------------------------------------------------
/*!
* \brief Class for hypotheses having several parameters modified by one method
};
DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
-
// -------------------------------------------------------------------------------------
/*!
* \brief Class representing NumberOfSegments hypothesis
// -------------------------------------------------------------------------------------
/*!
- * \brief Class representing smesh.Mesh_Algorithm
+ * \brief Class representing SegmentLengthAroundVertex hypothesis
*/
// -------------------------------------------------------------------------------------
-class _pyAlgorithm: public _pyHypothesis
+class _pySegmentLengthAroundVertexHyp: public _pyHypothesis
{
public:
- _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
+ _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
const _pyID& theMesh);
- const char* AccessorMethod() const { return "GetAlgorithm()"; }
-
- DEFINE_STANDARD_RTTI (_pyAlgorithm)
+ DEFINE_STANDARD_RTTI (_pySegmentLengthAroundVertexHyp)
};
+DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
#endif
case FT_BelongToGeom: myStream<< "aBelongToGeom"; break;
case FT_BelongToPlane: myStream<< "aBelongToPlane"; break;
case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
+ case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break;
case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break;
case FT_RangeOfIds: myStream<< "aRangeOfIds"; break;
case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
}
myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType );
- TPythonDump()<<this<<".SetSurface("<<theGeom<<",'"<<theType<<"')";
}
void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
return myElementsOnSurfacePtr->GetTolerance();
}
+void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions )
+{
+ myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions );
+ TPythonDump()<<this<<".SetUseBoundaries( " << theUseBndRestrictions << " )";
+}
+
+CORBA::Boolean BelongToSurface_i::GetUseBoundaries()
+{
+ return myElementsOnSurfacePtr->GetUseBoundaries();
+}
+
+
/*
Class : BelongToPlane_i
Description : Verify whether mesh element lie in pointed Geom planar object
return FT_BelongToCylinder;
}
+/*
+ Class : BelongToGenSurface_i
+ Description : Verify whether mesh element lie in pointed Geom planar object
+*/
+
+BelongToGenSurface_i::BelongToGenSurface_i()
+: BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
+{
+}
+
+void BelongToGenSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
+{
+ if ( theGeom->_is_nil() )
+ return;
+ TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
+ if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE )
+ aLocShape.Nullify();
+
+ BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
+ TPythonDump()<<this<<".SetGenSurface("<<theGeom<<","<<theType<<")";
+}
+
+FunctorType BelongToGenSurface_i::GetFunctorType()
+{
+ return FT_BelongToGenSurface;
+}
+
/*
Class : LyingOnGeom_i
Description : Predicate for selection on geometrical support
return anObj._retn();
}
+BelongToGenSurface_ptr FilterManager_i::CreateBelongToGenSurface()
+{
+ SMESH::BelongToGenSurface_i* aServant = new SMESH::BelongToGenSurface_i();
+ SMESH::BelongToGenSurface_var anObj = aServant->_this();
+ TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGenSurface()";
+ return anObj._retn();
+}
+
LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
{
SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
}
case FT_BelongToPlane:
case FT_BelongToCylinder:
+ case FT_BelongToGenSurface:
{
BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
ElementType aTypeOfElem = theCriteria[ i ].TypeOfElement;
long aPrecision = theCriteria[ i ].Precision;
- TPythonDump()<<"aCriteria.append(SMESH.Filter.Criterion("<<
+ TPythonDump()<<"aCriterion = SMESH.Filter.Criterion("<<
aCriterion<<","<<aCompare<<","<<aThreshold<<",'"<<aThresholdStr<<"','"<<aThresholdID<<"',"<<
aUnary<<","<<aBinary<<","<<aTolerance<<","<<aTypeOfElem<<","<<aPrecision<<"))";
break;
case SMESH::FT_BelongToPlane:
case SMESH::FT_BelongToCylinder:
+ case SMESH::FT_BelongToGenSurface:
{
- SMESH::BelongToSurface_ptr tmpPred;
- if ( aCriterion == SMESH::FT_BelongToPlane )
- tmpPred = aFilterMgr->CreateBelongToPlane();
- else
- tmpPred = aFilterMgr->CreateBelongToCylinder();
-
+ SMESH::BelongToSurface_ptr tmpPred;
+ switch ( aCriterion ) {
+ case SMESH::FT_BelongToPlane:
+ tmpPred = aFilterMgr->CreateBelongToPlane(); break;
+ case SMESH::FT_BelongToCylinder:
+ tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
+ default:
+ tmpPred = aFilterMgr->CreateBelongToGenSurface();
+ }
tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
tmpPred->SetTolerance( aTolerance );
aPredicate = tmpPred;
// logical op
aPredicates.push_back( aPredicate );
aBinaries.push_back( aBinary );
+ TPythonDump()<<"aCriteria.append(aCriterion)";
} // end of for
TPythonDump()<<this<<".SetCriteria(aCriteria)";
case FT_BelongToGeom : return "Belong to Geom";
case FT_BelongToPlane : return "Belong to Plane";
case FT_BelongToCylinder: return "Belong to Cylinder";
+ case FT_BelongToGenSurface: return "Belong to Generic Surface";
case FT_LyingOnGeom : return "Lying on Geom";
case FT_BadOrientedVolume: return "Bad Oriented Volume";
case FT_RangeOfIds : return "Range of IDs";
else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom;
else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane;
else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder;
+ else if ( theStr.equals( "Belong to Generic Surface" ) ) return FT_BelongToGenSurface;
else if ( theStr.equals( "Lying on Geom" ) ) return FT_LyingOnGeom;
else if ( theStr.equals( "Free borders" ) ) return FT_FreeBorders;
else if ( theStr.equals( "Free edges" ) ) return FT_FreeEdges;
void SetTolerance( CORBA::Double );
CORBA::Double GetTolerance();
+
+ void SetUseBoundaries( CORBA::Boolean theUseBndRestrictions );
+ CORBA::Boolean GetUseBoundaries();
protected:
Controls::ElementsOnSurfacePtr myElementsOnSurfacePtr;
FunctorType GetFunctorType();
};
+ /*
+ Class : BelongToGenSurface_i
+ Description : Verify whether mesh element lie on pointed Geom surfasic object
+ */
+ class BelongToGenSurface_i: public virtual POA_SMESH::BelongToGenSurface,
+ public virtual BelongToSurface_i
+ {
+ public:
+ BelongToGenSurface_i();
+ void SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType );
+ FunctorType GetFunctorType();
+ };
+
/*
Class : LyingOnGeom_i
Description : Predicate for selection on geometrical support(lying or partially lying)
BelongToGeom_ptr CreateBelongToGeom();
BelongToPlane_ptr CreateBelongToPlane();
BelongToCylinder_ptr CreateBelongToCylinder();
+ BelongToGenSurface_ptr CreateBelongToGenSurface();
LyingOnGeom_ptr CreateLyingOnGeom();
#include "SMDS_FacePosition.hxx"
#include "SMDS_VertexPosition.hxx"
#include "SMDS_SpacePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Filter)
const char* interfaceName )
: Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
{
- INFOS( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
+ MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
myOrb = CORBA::ORB::_duplicate(orb);
myPoa = PortableServer::POA::_duplicate(poa);
return false;
}
+//================================================================================
+/*!
+ * \brief Find SObject for an algo
+ */
+//================================================================================
+
+SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
+{
+ if ( algo ) {
+ if ( !myCurrentStudy->_is_nil() ) {
+ // find algo in the study
+ SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
+ ( myCurrentStudy->FindComponent( ComponentDataType() ) );
+ if ( !father->_is_nil() ) {
+ SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
+ for ( ; itBig->More(); itBig->Next() ) {
+ SALOMEDS::SObject_var gotBranch = itBig->Value();
+ if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
+ SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
+ for ( ; algoIt->More(); algoIt->Next() ) {
+ SALOMEDS::SObject_var algoSO = algoIt->Value();
+ CORBA::Object_var algoIOR = SObjectToObject( algoSO );
+ if ( !CORBA::is_nil( algoIOR )) {
+ SMESH_Hypothesis_i* impl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
+ if ( impl && impl->GetImpl() == algo )
+ return algoSO._retn();
+ }
+ } // loop on algo SO's
+ break;
+ } // if algo tag
+ } // SMESH component iterator
+ }
+ }
+ }
+ return SALOMEDS::SObject::_nil();
+}
+
+//================================================================================
+/*!
+ * \brief Return errors of mesh computation
+ */
+//================================================================================
+
+SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theSubObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" );
+
+ if ( CORBA::is_nil( theSubObject ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+ SMESH::compute_error_array_var error_array = new SMESH::compute_error_array;
+ try {
+ if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
+ {
+ TopoDS_Shape shape = GeomObjectToShape( theSubObject );
+ ::SMESH_Mesh& mesh = meshServant->GetImpl();
+
+ error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
+ int nbErr = 0;
+
+ SMESH_subMesh *sm = mesh.GetSubMesh(shape);
+ const bool includeSelf = true, complexShapeFirst = true;
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
+ complexShapeFirst);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
+ break;
+ SMESH_ComputeErrorPtr error = sm->GetComputeError();
+ if ( error && !error->IsOK() && error->myAlgo )
+ {
+ SMESH::ComputeError & errStruct = error_array[ nbErr++ ];
+ errStruct.code = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
+ errStruct.comment = error->myComment.c_str();
+ errStruct.subShapeID = sm->GetId();
+ SALOMEDS::SObject_var algoSO = GetAlgoSO( error->myAlgo );
+ if ( !algoSO->_is_nil() )
+ errStruct.algoName = algoSO->GetName();
+ else
+ errStruct.algoName = error->myAlgo->GetName();
+ }
+ }
+ error_array->length( nbErr );
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+
+ return error_array._retn();
+}
+
//================================================================================
/*!
* \brief Returns errors of hypotheses definintion
int i = 0;
for ( error = error_list.begin(); error != error_list.end(); ++error )
{
- // error name
- SMESH::AlgoStateErrorName errName;
- switch ( error->_name ) {
- case ::SMESH_Gen::MISSING_ALGO: errName = SMESH::MISSING_ALGO; break;
- case ::SMESH_Gen::MISSING_HYPO: errName = SMESH::MISSING_HYPO; break;
- case ::SMESH_Gen::NOT_CONFORM_MESH: errName = SMESH::NOT_CONFORM_MESH; break;
- case ::SMESH_Gen::BAD_PARAM_VALUE: errName = SMESH::BAD_PARAM_VALUE; break;
- default:
- THROW_SALOME_CORBA_EXCEPTION( "bad error name",SALOME::BAD_PARAM );
- }
- // algo name
- CORBA::String_var algoName;
- if ( error->_algo ) {
- if ( !myCurrentStudy->_is_nil() ) {
- // find algo in the study
- SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
- ( myCurrentStudy->FindComponent( ComponentDataType() ) );
- if ( !father->_is_nil() ) {
- SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
- for ( ; itBig->More(); itBig->Next() ) {
- SALOMEDS::SObject_var gotBranch = itBig->Value();
- if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
- SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
- for ( ; algoIt->More(); algoIt->Next() ) {
- SALOMEDS::SObject_var algoSO = algoIt->Value();
- CORBA::Object_var algoIOR = SObjectToObject( algoSO );
- if ( !CORBA::is_nil( algoIOR )) {
- SMESH_Hypothesis_i* myImpl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
- if ( myImpl && myImpl->GetImpl() == error->_algo ) {
- algoName = algoSO->GetName();
- break;
- }
- }
- } // loop on algo SO's
- break;
- } // if algo tag
- } // SMESH component iterator
- }
- }
- if ( algoName.in() == 0 )
- // use algo type name
- algoName = CORBA::string_dup( error->_algo->GetName() );
- }
// fill AlgoStateError structure
SMESH::AlgoStateError & errStruct = error_array[ i++ ];
- errStruct.name = errName;
- errStruct.algoName = algoName;
+ errStruct.state = SMESH_Mesh_i::ConvertHypothesisStatus( error->_name );
errStruct.algoDim = error->_algoDim;
errStruct.isGlobalAlgo = error->_isGlobalAlgo;
+ errStruct.algoName = "";
+ SALOMEDS::SObject_var algoSO = GetAlgoSO( error->_algo );
+ if ( !algoSO->_is_nil() )
+ errStruct.algoName = algoSO->GetName();
}
}
}
GEOM::GEOM_Gen_var geomGen = GetGeomEngine();
// try to find the corresponding SObject
- GeomObjectToShape( geom ); // geom client remembers the found shape
SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
- if ( SObj->_is_nil() )
- // publish a new subshape
+ if ( SObj->_is_nil() ) // submesh can be not found even if published
+ {
+ // try to find published submesh
+ GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+ if ( !geom->IsMainShape() && list->length() == 1 ) {
+ SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+ SALOMEDS::ChildIterator_var it;
+ if ( !mainSO->_is_nil() )
+ it = myCurrentStudy->NewChildIterator( mainSO );
+ if ( !it->_is_nil() ) {
+ for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) {
+ GEOM::GEOM_Object_var subGeom =
+ GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+ if ( !subGeom->_is_nil() ) {
+ GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
+ if ( subList->length() == 1 && list[0] == subList[0] ) {
+ SObj = it->Value();
+ geom = subGeom;
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( SObj->_is_nil() ) // publish a new subshape
SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
+
// return only published geometry
if ( !SObj->_is_nil() )
return geom._retn();
return GEOM::GEOM_Object::_nil();
}
-
//================================================================================
/*!
* \brief Return geometrical object the given element is built on.
GEOM::GEOM_Object_ptr
SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh,
- CORBA::Long theElementID)
+ CORBA::Long theElementID)
throw ( SALOME::SALOME_Exception )
{
Unexpect aCatch(SALOME_SalomeException);
if ( !op->_is_nil() )
geom = op->GetSubShape( mainShape, shapeID );
}
- if ( !geom->_is_nil() )
+ if ( !geom->_is_nil() ) {
+ GeomObjectToShape( geom ); // let geom client remember the found shape
return geom._retn();
+ }
}
}
return GEOM::GEOM_Object::_nil();
}
+//================================================================================
+/*!
+ * SMESH_Gen_i::Concatenate
+ *
+ * Concatenate the given meshes into one mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
+ CORBA::Boolean theUniteIdenticalGroups,
+ CORBA::Boolean theMergeNodesAndElements,
+ CORBA::Double theMergeTolerance)
+ throw ( SALOME::SALOME_Exception )
+{
+ typedef map<int, int> TIDsMap;
+ typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
+ typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
+ typedef std::set<SMESHDS_GroupBase*> TGroups;
+
+ TPythonDump aPythonDump; // prevent dump of called methods
+
+ // create mesh
+ SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
+
+ if ( !aNewMesh->_is_nil() ) {
+ SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
+ if ( aNewImpl ) {
+ ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
+ SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
+
+ TGroupsMap aGroupsMap;
+ TListOfNewGroups aListOfNewGroups;
+ SMESH_MeshEditor aNewEditor = ::SMESH_MeshEditor(&aLocMesh);
+ SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
+
+ // loop on meshes
+ for ( int i = 0; i < theMeshesArray.length(); i++) {
+ SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
+ if ( !anInitMesh->_is_nil() ) {
+ SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
+ if ( anInitImpl ) {
+ ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+ SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+ TIDsMap nodesMap;
+ TIDsMap elemsMap;
+
+ // loop on elements of mesh
+ SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
+ const SMDS_MeshElement* anElem = 0;
+ const SMDS_MeshElement* aNewElem = 0;
+ int anElemNbNodes = 0;
+
+ for ( int j = 0; itElems->more(); j++) {
+ anElem = itElems->next();
+ SMDSAbs_ElementType anElemType = anElem->GetType();
+ anElemNbNodes = anElem->NbNodes();
+ std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
+
+ // loop on nodes of element
+ const SMDS_MeshNode* aNode = 0;
+ const SMDS_MeshNode* aNewNode = 0;
+ SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+
+ for ( int k = 0; itNodes->more(); k++) {
+ aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
+ if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
+ aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+ nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+ }
+ else
+ aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
+ aNodesArray[k] = aNewNode;
+ }//nodes loop
+
+ // creates a corresponding element on existent nodes in new mesh
+ if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
+ {
+ const SMDS_PolyhedralVolumeOfNodes* aVolume =
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+ if ( aVolume ) {
+ aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
+ aVolume->GetQuanities());
+ elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+ }
+ }
+ else {
+
+ aNewElem = aNewEditor.AddElement(aNodesArray,
+ anElemType,
+ anElem->IsPoly());
+ elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+ }
+ }//elems loop
+
+ aListOfGroups = anInitImpl->GetGroups();
+ SMESH::SMESH_GroupBase_ptr aGroup;
+
+ // loop on groups of mesh
+ SMESH::long_array_var anInitIDs = new SMESH::long_array();
+ SMESH::long_array_var anNewIDs = new SMESH::long_array();
+ SMESH::SMESH_Group_var aNewGroup;
+ for (int i = 0; i < aListOfGroups->length(); i++) {
+ aGroup = aListOfGroups[i];
+ aListOfNewGroups.clear();
+ SMESH::ElementType aGroupType = aGroup->GetType();
+ CORBA::String_var aGroupName = aGroup->GetName();
+
+ TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
+
+ // convert a list of IDs
+ anInitIDs = aGroup->GetListOfID();
+ anNewIDs->length(anInitIDs->length());
+ if ( aGroupType == SMESH::NODE )
+ for (int j = 0; j < anInitIDs->length(); j++) {
+ anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
+ }
+ else
+ for (int j = 0; j < anInitIDs->length(); j++) {
+ anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
+ }
+
+ // check that current group name and type don't have identical ones in union mesh
+ if ( anIter == aGroupsMap.end() ) {
+ // add a new group in the mesh
+ aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+ // add elements into new group
+ aNewGroup->Add( anNewIDs );
+
+ aListOfNewGroups.push_back(aNewGroup);
+ aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+ }
+
+ else if ( theUniteIdenticalGroups ) {
+ // unite identical groups
+ TListOfNewGroups& aNewGroups = anIter->second;
+ aNewGroups.front()->Add( anNewIDs );
+ }
+
+ else {
+ // rename identical groups
+ aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+ aNewGroup->Add( anNewIDs );
+
+ TListOfNewGroups& aNewGroups = anIter->second;
+ string aNewGroupName;
+ if (aNewGroups.size() == 1) {
+ aNewGroupName = string(aGroupName) + "_1";
+ aNewGroups.front()->SetName(aNewGroupName.c_str());
+ }
+ char aGroupNum[128];
+ sprintf(aGroupNum, "%u", aNewGroups.size()+1);
+ aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
+ aNewGroup->SetName(aNewGroupName.c_str());
+ aNewGroups.push_back(aNewGroup);
+ }
+ }//groups loop
+ }
+ }
+ }//meshes loop
+
+ if (theMergeNodesAndElements) {
+ // merge nodes
+ set<const SMDS_MeshNode*> aMeshNodes; // no input nodes
+ SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+ aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
+ aNewEditor.MergeNodes( aGroupsOfNodes );
+ // merge elements
+ aNewEditor.MergeEqualElements();
+ }
+ }
+ }
+
+ // Update Python script
+ aPythonDump << aNewMesh << " = " << this << ".Concatenate(";
+ aPythonDump << "[";
+ for ( int i = 0; i < theMeshesArray.length(); i++) {
+ if (i > 0) aPythonDump << ", ";
+ aPythonDump << theMeshesArray[i];
+ }
+ aPythonDump << "], ";
+ aPythonDump << theUniteIdenticalGroups << ", "
+ << theMergeNodesAndElements << ", "
+ << theMergeTolerance << ")";
+
+ return aNewMesh._retn();
+}
+
//=============================================================================
/*!
* SMESH_Gen_i::Save
aDataset->CloseOnDisk();
// get elements sorted by ID
- ::SMESH_MeshEditor::TIDSortedElemSet elemSet;
+ TIDSortedElemSet elemSet;
if ( isNode )
while ( nIt->more() ) elemSet.insert( nIt->next() );
else
ASSERT( elemSet.size() == nbElems );
// add elements to submeshes
- ::SMESH_MeshEditor::TIDSortedElemSet::iterator iE = elemSet.begin();
+ TIDSortedElemSet::iterator iE = elemSet.begin();
for ( int i = 0; i < nbElems; ++i, ++iE )
{
int smID = smIDs[ i ];
sm->AddElement( elem );
}
}
- delete smIDs;
+ delete [] smIDs;
}
}
} // end reading submeshes
// Compute mesh on a shape
CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
- GEOM::GEOM_Object_ptr theShapeObject )
+ GEOM::GEOM_Object_ptr theShapeObject )
+ throw ( SALOME::SALOME_Exception );
+ /*!
+ * \brief Return errors of mesh computation
+ */
+ SMESH::compute_error_array* GetComputeErrors(SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject )
throw ( SALOME::SALOME_Exception );
// Returns true if mesh contains enough data to be computed
CORBA::Long theElementID)
throw ( SALOME::SALOME_Exception );
+ // Concatenate the given meshes into one mesh
+ SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray,
+ CORBA::Boolean theUniteIdenticalGroups,
+ CORBA::Boolean theMergeNodesAndElements,
+ CORBA::Double theMergeTolerance)
+ throw ( SALOME::SALOME_Exception );
+
+
// ****************************************************
// Interface inherited methods (from SALOMEDS::Driver)
// ****************************************************
// Get current study ID
int GetCurrentStudyID()
{ return myCurrentStudy->_is_nil() ? -1 : myCurrentStudy->StudyId(); }
+
+ /*!
+ * \brief Find SObject for an algo
+ */
+ SALOMEDS::SObject_ptr GetAlgoSO(const ::SMESH_Algo* algo);
private:
// Create hypothesis of given type
#include "SMDS_MeshEdge.hxx"
#include "SMDS_MeshFace.hxx"
#include "SMDS_MeshVolume.hxx"
-
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMESH_MeshEditor.hxx"
-
+#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen_i.hxx"
#include "SMESH_Filter_i.hxx"
#include "SMESH_PythonDump.hxx"
#include <sstream>
-typedef map<const SMDS_MeshElement*,
- list<const SMDS_MeshElement*> > TElemOfElemListMap;
+#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
using namespace std;
using SMESH::TPythonDump;
+namespace {
+
+ //=============================================================================
+ /*!
+ * \brief Mesh to apply modifications for preview purposes
+ */
+ //=============================================================================
+
+ struct TPreviewMesh: public SMESH_Mesh
+ {
+ SMDSAbs_ElementType myPreviewType; // type to show
+ //!< Constructor
+ TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
+ _isShapeToMesh = _id =_studyId =_idDoc = 0;
+ _myMeshDS = new SMESHDS_Mesh( _id, true );
+ myPreviewType = previewElements;
+ }
+ //!< Destructor
+ virtual ~TPreviewMesh() { delete _myMeshDS; }
+ //!< Copy a set of elements
+ void Copy(const TIDSortedElemSet & theElements,
+ TIDSortedElemSet& theCopyElements,
+ SMDSAbs_ElementType theSelectType = SMDSAbs_All,
+ SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
+ {
+ // loop on theIDsOfElements
+ TIDSortedElemSet::const_iterator eIt = theElements.begin();
+ for ( ; eIt != theElements.end(); ++eIt )
+ {
+ const SMDS_MeshElement* anElem = *eIt;
+ if ( !anElem ) continue;
+ SMDSAbs_ElementType type = anElem->GetType();
+ if ( type == theAvoidType ||
+ ( theSelectType != SMDSAbs_All && type != theSelectType ))
+ continue;
+
+ if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
+ theCopyElements.insert( theCopyElements.end(), anElemCopy );
+ }
+ }
+ //!< Copy an element
+ SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
+ {
+ // copy element nodes
+ int anElemNbNodes = anElem->NbNodes();
+ vector< int > anElemNodesID( anElemNbNodes ) ;
+ SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
+ for ( int i = 0; itElemNodes->more(); i++)
+ {
+ const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
+ Copy( anElemNode );
+ anElemNodesID[i] = anElemNode->GetID();
+ }
+
+ // creates a corresponding element on copied nodes
+ SMDS_MeshElement* anElemCopy = 0;
+ if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
+ {
+ const SMDS_PolyhedralVolumeOfNodes* ph =
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+ if ( ph )
+ anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
+ (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+ }
+ else {
+ anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
+ anElem->GetType(),
+ anElem->IsPoly() );
+ }
+ return anElemCopy;
+ }
+ //!< Copy a node
+ SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
+ {
+ return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
+ anElemNode->GetID());
+ }
+ };// struct TPreviewMesh
+
+ static SMESH_NodeSearcher * myNodeSearcher = 0;
+
+ //=============================================================================
+ /*!
+ * \brief Deleter of myNodeSearcher at any compute event occured
+ */
+ //=============================================================================
+
+ struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
+ {
+ SMESH_Mesh* myMesh;
+ //!< Constructor
+ TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
+ myMesh(0) {}
+ //!< Delete myNodeSearcher
+ static void Delete()
+ {
+ if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
+ }
+ typedef map < int, SMESH_subMesh * > TDependsOnMap;
+ //!< The meshod called by submesh: do my main job
+ void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
+ SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
+ {
+ if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
+ Delete();
+ Unset( sm->GetFather() );
+ }
+ }
+ //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
+ void Set(SMESH_Mesh* mesh)
+ {
+ if ( myMesh && myMesh != mesh ) {
+ Delete();
+ Unset( myMesh );
+ }
+ myMesh = mesh;
+ if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+ const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+ TDependsOnMap::const_iterator sm;
+ for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+ sm->second->SetEventListener( this, 0, sm->second );
+ }
+ }
+ //!< delete self from all submeshes
+ void Unset(SMESH_Mesh* mesh)
+ {
+ if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+ const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+ TDependsOnMap::const_iterator sm;
+ for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+ sm->second->DeleteEventListener( this );
+ }
+ }
+ };
+}
+
//=============================================================================
/*!
*
*/
//=============================================================================
-SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
+SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh, bool isPreview)
+{
+ myMesh = theMesh;
+ myPreviewMode = isPreview;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
{
- _myMesh = theMesh;
+}
+
+//================================================================================
+/*!
+ * \brief Clear members
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::initData()
+{
+ if ( myPreviewMode ) {
+ myPreviewData = new SMESH::MeshPreviewStruct();
+ }
+ else {
+ myLastCreatedElems = new SMESH::long_array();
+ myLastCreatedNodes = new SMESH::long_array();
+ TNodeSearcherDeleter::Delete();
+ }
}
//=============================================================================
CORBA::Boolean
SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
list< int > IdList;
for (int i = 0; i < IDsOfElements.length(); i++)
CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
list< int > IdList;
for (int i = 0; i < IDsOfNodes.length(); i++)
IdList.push_back( IDsOfNodes[i] );
CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbNodes = IDsOfNodes.length();
SMDS_MeshElement* elem = 0;
CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
CORBA::Double y, CORBA::Double z)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbNodes = IDsOfNodes.length();
if (NbNodes < 3)
CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
(const SMESH::long_array & IDsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbNodes = IDsOfNodes.length();
std::vector<const SMDS_MeshNode*> nodes (NbNodes);
CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbNodes = IDsOfNodes.length();
vector< const SMDS_MeshNode*> n(NbNodes);
(const SMESH::long_array & IDsOfNodes,
const SMESH::long_array & Quantities)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbNodes = IDsOfNodes.length();
std::vector<const SMDS_MeshNode*> n (NbNodes);
CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
(const SMESH::long_array & IdsOfFaces)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
int NbFaces = IdsOfFaces.length();
std::vector<const SMDS_MeshNode*> poly_nodes;
CORBA::Double y,
CORBA::Double z)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
if ( !node )
CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
CORBA::Long NodeID2)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
TPythonDump() << "isDone = " << this << ".InverseDiag( "
<< NodeID1 << ", " << NodeID2 << " )";
- ::SMESH_MeshEditor aMeshEditor( _myMesh );
+ ::SMESH_MeshEditor aMeshEditor( myMesh );
return aMeshEditor.InverseDiag ( n1, n2 );
}
CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
CORBA::Long NodeID2)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
TPythonDump() << "isDone = " << this << ".DeleteDiag( "
<< NodeID1 << ", " << NodeID2 << " )";
- ::SMESH_MeshEditor aMeshEditor( _myMesh );
+ ::SMESH_MeshEditor aMeshEditor( myMesh );
bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
- UpdateLastResult(aMeshEditor);
+ StoreResult(aMeshEditor);
return stat;
}
CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
for (int i = 0; i < IDsOfElements.length(); i++)
{
CORBA::Long index = IDsOfElements[i];
CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
CORBA::Boolean isDone = Reorient(anElementsId);
return isDone;
}
-
-//=======================================================================
-//function : ToMap
-//purpose : auxilary function for conversion long_array to std::map<>
-// which is used in some methods
-//=======================================================================
-static void ToMap(const SMESH::long_array & IDs,
- const SMESHDS_Mesh* aMesh,
- std::map<int,const SMDS_MeshElement*>& aMap,
- const SMDSAbs_ElementType aType = SMDSAbs_All )
-{
- for (int i=0; i<IDs.length(); i++) {
- CORBA::Long ind = IDs[i];
- std::map<int,const SMDS_MeshElement*>::iterator It = aMap.find(ind);
- if(It==aMap.end()) {
+namespace
+{
+ //================================================================================
+ /*!
+ * \brief function for conversion long_array to TIDSortedElemSet
+ * \param IDs - array of IDs
+ * \param aMesh - mesh
+ * \param aMap - collection to fill
+ * \param aType - element type
+ */
+ //================================================================================
+
+ void ToMap(const SMESH::long_array & IDs,
+ const SMESHDS_Mesh* aMesh,
+ TIDSortedElemSet& aMap,
+ const SMDSAbs_ElementType aType = SMDSAbs_All )
+ {
+ for (int i=0; i<IDs.length(); i++) {
+ CORBA::Long ind = IDs[i];
const SMDS_MeshElement * elem = aMesh->FindElement(ind);
if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
- aMap.insert( make_pair( elem->GetID(), elem ));
+ aMap.insert( elem );
}
}
}
-
//=============================================================================
/*!
*
SMESH::NumericalFunctor_ptr Criterion,
CORBA::Double MaxAngle)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> faces;
+ TIDSortedElemSet faces;
ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
SMESH::NumericalFunctor_i* aNumericalFunctor =
TPythonDump() << "print 'TriToQuad: ', isDone";
#endif
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return stat;
}
SMESH::NumericalFunctor_ptr Criterion,
CORBA::Double MaxAngle)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
SMESH::NumericalFunctor_ptr Criterion)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> faces;
+ TIDSortedElemSet faces;
ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
SMESH::NumericalFunctor_i* aNumericalFunctor =
TPythonDump() << "print 'QuadToTri: ', isDone";
#endif
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return stat;
}
CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
SMESH::NumericalFunctor_ptr Criterion)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
CORBA::Boolean Diag13)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> faces;
+ TIDSortedElemSet faces;
ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
// Update Python script
TPythonDump() << "print 'SplitQuad: ', isDone";
#endif
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return stat;
}
CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
CORBA::Boolean Diag13)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
else
aCrit.reset(new SMESH::Controls::AspectRatio());
- ::SMESH_MeshEditor anEditor (_myMesh);
+ ::SMESH_MeshEditor anEditor (myMesh);
return anEditor.BestSplit(quad, aCrit);
}
return -1;
SMESH::SMESH_MeshEditor::Smooth_Method Method,
bool IsParametric)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(IDsOfElements, aMesh, elements, SMDSAbs_Face);
set<const SMDS_MeshNode*> fixedNodes;
if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
method = ::SMESH_MeshEditor::CENTROIDAL;
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.Smooth(elements, fixedNodes, method,
MaxNbOfIterations, MaxAspectRatio, IsParametric );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
// Update Python script
TPythonDump() << "isDone = " << this << "."
SMESH::SMESH_MeshEditor::Smooth_Method Method,
bool IsParametric)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
CORBA::Long theNbOfSteps,
CORBA::Double theTolerance)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
- SMESHDS_Mesh* aMesh = GetMeshDS();
+ TIDSortedElemSet inElements, copyElements;
+ ToMap(theIDsOfElements, GetMeshDS(), inElements);
- map<int,const SMDS_MeshElement*> elements;
- ToMap(theIDsOfElements, aMesh, elements);
+ TIDSortedElemSet* workElements = & inElements;
+ TPreviewMesh tmpMesh( SMDSAbs_Face );
+ SMESH_Mesh* mesh = 0;
+ bool makeWalls=true;
+ if ( myPreviewMode )
+ {
+ SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+ tmpMesh.Copy( inElements, copyElements, select, avoid );
+ mesh = &tmpMesh;
+ workElements = & copyElements;
+ //makeWalls = false;
+ }
+ else
+ {
+ mesh = myMesh;
+ }
- gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
+ gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
- ::SMESH_MeshEditor anEditor( _myMesh );
- anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
- theNbOfSteps, theTolerance);
+ ::SMESH_MeshEditor anEditor( mesh );
+ anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
+ theNbOfSteps, theTolerance, makeWalls);
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
- // Update Python script
- TPythonDump() << "axis = " << theAxis;
- TPythonDump() << this << ".RotationSweep( "
- << theIDsOfElements
- << ", axis, "
- << theAngleInRadians << ", "
- << theNbOfSteps << ", "
- << theTolerance << " )";
+ if ( !myPreviewMode ) {
+ // Update Python script
+ TPythonDump() << "axis = " << theAxis;
+ TPythonDump() << this << ".RotationSweep( "
+ << theIDsOfElements
+ << ", axis, "
+ << theAngleInRadians << ", "
+ << theNbOfSteps << ", "
+ << theTolerance << " )";
+ }
}
//=======================================================================
CORBA::Long theNbOfSteps,
CORBA::Double theTolerance)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
#ifdef NO_CAS_CATCH
try {
#endif
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
const SMESH::PointStruct * P = &theStepVector.PS;
gp_Vec stepVec( P->x, P->y, P->z );
TElemOfElemListMap aHystory;
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
// Update Python script
TPythonDump() << "stepVector = " << theStepVector;
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
SMESH::long_array_var allElementsId = theObject->GetIDs();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(allElementsId, aMesh, elements);
const SMESH::PointStruct * P = &theStepVector.PS;
gp_Vec stepVec( P->x, P->y, P->z );
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
//anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
TElemOfElemListMap aHystory;
anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
// Update Python script
TPythonDump() << "stepVector = " << theStepVector;
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
SMESH::long_array_var allElementsId = theObject->GetIDs();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(allElementsId, aMesh, elements);
const SMESH::PointStruct * P = &theStepVector.PS;
gp_Vec stepVec( P->x, P->y, P->z );
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
//anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
TElemOfElemListMap aHystory;
anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
// Update Python script
TPythonDump() << "stepVector = " << theStepVector;
CORBA::Long theExtrFlags,
CORBA::Double theSewTolerance)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
const SMESH::PointStruct * P = &theStepVector.PS;
gp_Vec stepVec( P->x, P->y, P->z );
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
TElemOfElemListMap aHystory;
anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
theExtrFlags, theSewTolerance);
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
// Update Python script
TPythonDump() << "stepVector = " << theStepVector;
CORBA::Boolean theHasRefPoint,
const SMESH::PointStruct & theRefPoint)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
if ( !nodeStart )
return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
list<double> angles;
gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
// Update Python script
- TPythonDump() << "refPoint = SMESH.PointStruct( "
- << refPnt.X() << ", "
- << refPnt.Y() << ", "
- << refPnt.Z() << " )";
+ TPythonDump() << "rotAngles = " << theAngles;
+
+ if ( theHasRefPoint )
+ TPythonDump() << "refPoint = SMESH.PointStruct( "
+ << refPnt.X() << ", "
+ << refPnt.Y() << ", "
+ << refPnt.Z() << " )";
+ else
+ TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
+
TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
<< theIDsOfElements << ", "
- << thePathMesh << ", "
- << thePathShape << ", "
- << theNodeStart << ", "
- << theHasAngles << ", "
- << theAngles << ", "
- << theHasRefPoint << ", refPoint )";
-
- ::SMESH_MeshEditor anEditor( _myMesh );
+ << thePathMesh << ", "
+ << thePathShape << ", "
+ << theNodeStart << ", "
+ << theHasAngles << ", "
+ << "rotAngles" << ", "
+ << theHasRefPoint << ", refPoint )";
+
+ ::SMESH_MeshEditor anEditor( myMesh );
SMESH::SMESH_MeshEditor::Extrusion_Error error =
convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
theHasAngles, angles,
theHasRefPoint, refPnt ) );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return error;
}
CORBA::Boolean theHasRefPoint,
const SMESH::PointStruct & theRefPoint)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
SMESH::SMESH_MeshEditor::Extrusion_Error error = ExtrusionAlongPath
aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
// Update Python script
+ TPythonDump() << "rotAngles = " << theAngles;
TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
<< theObject << ", "
<< thePathMesh << ", "
<< thePathShape << ", "
<< theNodeStart << ", "
<< theHasAngles << ", "
- << theAngles << ", "
- << theHasRefPoint << ", refPoint )";
+ << "rotAngles" << ", "
+ << theHasRefPoint<<", refPoint )";
return error;
}
+//================================================================================
+/*!
+ * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
+ * of given angles along path steps
+ * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
+ * which proceeds the extrusion
+ * \param PathShape is shape(edge); as the mesh can be complex, the edge
+ * is used to define the sub-mesh for the path
+ */
+//================================================================================
+
+SMESH::double_array*
+SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
+ GEOM::GEOM_Object_ptr thePathShape,
+ const SMESH::double_array & theAngles)
+{
+ SMESH::double_array_var aResult = new SMESH::double_array();
+ return aResult._retn();
+}
+
//=======================================================================
//function : Mirror
//purpose :
SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
<< typeStr << ", "
<< theCopy << " )";
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.Transform (elements, aTrsf, theCopy);
if(theCopy) {
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
}
}
SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
Mirror(anElementsId, theAxis, theMirrorType, theCopy);
const SMESH::DirStruct & theVector,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
gp_Trsf aTrsf;
const SMESH::PointStruct * P = &theVector.PS;
aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.Transform (elements, aTrsf, theCopy);
if(theCopy) {
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
}
// Update Python script
const SMESH::DirStruct & theVector,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
Translate(anElementsId, theVector, theCopy);
CORBA::Double theAngle,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
- map<int,const SMDS_MeshElement*> elements;
+ TIDSortedElemSet elements;
ToMap(theIDsOfElements, aMesh, elements);
gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
gp_Trsf aTrsf;
aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.Transform (elements, aTrsf, theCopy);
if(theCopy) {
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
}
// Update Python script
CORBA::Double theAngle,
CORBA::Boolean theCopy)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESH::long_array_var anElementsId = theObject->GetIDs();
Rotate(anElementsId, theAxis, theAngle, theCopy);
void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
SMESH::array_of_long_array_out GroupsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
set<const SMDS_MeshNode*> nodes; // no input nodes
anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
<< Tolerance << " )";
}
+//=======================================================================
+//function : FindCoincidentNodesOnPart
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
+ CORBA::Double Tolerance,
+ SMESH::array_of_long_array_out GroupsOfNodes)
+{
+ initData();
+ SMESH::long_array_var aElementsId = theObject->GetIDs();
+
+ SMESHDS_Mesh* aMesh = GetMeshDS();
+ set<const SMDS_MeshNode*> nodes;
+
+ if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
+ SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
+ for(int i = 0; i < aElementsId->length(); i++) {
+ CORBA::Long ind = aElementsId[i];
+ const SMDS_MeshNode * elem = aMesh->FindNode(ind);
+ if(elem)
+ nodes.insert(elem);
+ }
+ }
+ else {
+ for(int i = 0; i < aElementsId->length(); i++) {
+ CORBA::Long ind = aElementsId[i];
+ const SMDS_MeshElement * elem = aMesh->FindElement(ind);
+ if(elem) {
+ SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+ while ( nIt->more() )
+ nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
+ }
+ }
+ }
+
+
+ ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
+ ::SMESH_MeshEditor anEditor( myMesh );
+ if(!nodes.empty())
+ anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+
+ GroupsOfNodes = new SMESH::array_of_long_array;
+ GroupsOfNodes->length( aListOfListOfNodes.size() );
+ ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
+ for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
+ list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
+ list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
+ SMESH::long_array& aGroup = GroupsOfNodes[ i ];
+ aGroup.length( aListOfNodes.size() );
+ for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
+ aGroup[ j ] = (*lIt)->GetID();
+ }
+ // Update Python script
+ TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
+ <<theObject<<", "
+ << Tolerance << " )";
+}
+
//=======================================================================
//function : MergeNodes
//purpose :
void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
if ( i > 0 ) aTPythonDump << ", ";
aTPythonDump << aNodeGroup;
}
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.MergeNodes( aListOfListOfNodes );
// Update Python script
aTPythonDump << "])";
}
+//=======================================================================
+//function : FindEqualElements
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
+ SMESH::array_of_long_array_out GroupsOfElementsID)
+{
+ initData();
+ if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
+ SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
+ typedef list<int> TListOfIDs;
+ set<const SMDS_MeshElement*> elems;
+ SMESH::long_array_var aElementsId = theObject->GetIDs();
+ SMESHDS_Mesh* aMesh = GetMeshDS();
+
+ for(int i = 0; i < aElementsId->length(); i++) {
+ CORBA::Long anID = aElementsId[i];
+ const SMDS_MeshElement * elem = aMesh->FindElement(anID);
+ if (elem) {
+ elems.insert(elem);
+ }
+ }
+
+ ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
+ ::SMESH_MeshEditor anEditor( myMesh );
+ anEditor.FindEqualElements( elems, aListOfListOfElementsID );
+
+ GroupsOfElementsID = new SMESH::array_of_long_array;
+ GroupsOfElementsID->length( aListOfListOfElementsID.size() );
+
+ ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
+ for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
+ SMESH::long_array& aGroup = GroupsOfElementsID[ j ];
+ TListOfIDs& listOfIDs = *arraysIt;
+ aGroup.length( listOfIDs.size() );
+ TListOfIDs::iterator idIt = listOfIDs.begin();
+ for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
+ aGroup[ k ] = *idIt;
+ }
+ }
+
+ // Update Python script
+ TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
+ <<theObject<<" )";
+ }
+}
+
+//=======================================================================
+//function : MergeElements
+//purpose :
+//=======================================================================
+
+void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
+{
+ initData();
+
+ TPythonDump aTPythonDump;
+ aTPythonDump << this << ".MergeElements( [";
+
+ ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
+
+ for (int i = 0; i < GroupsOfElementsID.length(); i++) {
+ const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
+ aListOfListOfElementsID.push_back( list< int >() );
+ list< int >& aListOfElemsID = aListOfListOfElementsID.back();
+ for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
+ CORBA::Long id = anElemsIDGroup[ j ];
+ aListOfElemsID.push_back( id );
+ }
+ if ( aListOfElemsID.size() < 2 )
+ aListOfListOfElementsID.pop_back();
+ if ( i > 0 ) aTPythonDump << ", ";
+ aTPythonDump << anElemsIDGroup;
+ }
+
+ ::SMESH_MeshEditor anEditor( myMesh );
+ anEditor.MergeElements(aListOfListOfElementsID);
+
+ // Update Python script
+ aTPythonDump << "] )";
+}
+
//=======================================================================
//function : MergeEqualElements
//purpose :
void SMESH_MeshEditor_i::MergeEqualElements()
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.MergeEqualElements();
// Update Python script
TPythonDump() << this << ".MergeEqualElements()";
}
+//================================================================================
+/*!
+ * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
+ * move the node closest to the point to point's location and return ID of the node
+ */
+//================================================================================
+
+CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
+ CORBA::Double y,
+ CORBA::Double z,
+ CORBA::Long theNodeID)
+{
+ // We keep myNodeSearcher until any mesh modification:
+ // 1) initData() deletes myNodeSearcher at any edition,
+ // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
+
+ initData();
+
+ int nodeID = theNodeID;
+ const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
+ if ( !node )
+ {
+ static TNodeSearcherDeleter deleter;
+ deleter.Set( myMesh );
+ if ( !myNodeSearcher ) {
+ ::SMESH_MeshEditor anEditor( myMesh );
+ myNodeSearcher = anEditor.GetNodeSearcher();
+ }
+ gp_Pnt p( x,y,z );
+ node = myNodeSearcher->FindClosestTo( p );
+ }
+ if ( node ) {
+ nodeID = node->GetID();
+ if ( myPreviewMode ) // make preview data
+ {
+ // in a preview mesh, make edges linked to a node
+ TPreviewMesh tmpMesh;
+ TIDSortedElemSet linkedNodes;
+ ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
+ TIDSortedElemSet::iterator nIt = linkedNodes.begin();
+ for ( ; nIt != linkedNodes.end(); ++nIt )
+ {
+ SMDS_MeshEdge edge( node, cast2Node( *nIt ));
+ tmpMesh.Copy( &edge );
+ }
+ // move copied node
+ node = tmpMesh.GetMeshDS()->FindNode( nodeID );
+ if ( node )
+ tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
+ // fill preview data
+ ::SMESH_MeshEditor anEditor( & tmpMesh );
+ StoreResult( anEditor );
+ }
+ else
+ {
+ GetMeshDS()->MoveNode(node, x, y, z);
+ }
+ }
+
+ if ( !myPreviewMode ) {
+ // Update Python script
+ TPythonDump() << "nodeID = " << this
+ << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << " )";
+ }
+
+ return nodeID;
+}
+
//=======================================================================
-//function : operator
+//function : convError
//purpose :
//=======================================================================
CORBA::Boolean CreatePolygons,
CORBA::Boolean CreatePolyedrs)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
<< CreatePolygons<< ", "
<< CreatePolyedrs<< " )";
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( anEditor.SewFreeBorder (aBorderFirstNode,
aBorderSecondNode,
CreatePolygons,
CreatePolyedrs) );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return error;
}
CORBA::Long FirstNodeID2,
CORBA::Long SecondNodeID2)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
<< FirstNodeID2 << ", "
<< SecondNodeID2 << " )";
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( anEditor.SewFreeBorder (aBorderFirstNode,
aBorderSecondNode,
true,
false, false) );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return error;
}
CORBA::Boolean CreatePolygons,
CORBA::Boolean CreatePolyedrs)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
<< CreatePolygons << ", "
<< CreatePolyedrs << ") ";
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( anEditor.SewFreeBorder (aBorderFirstNode,
aBorderSecondNode,
CreatePolygons,
CreatePolyedrs) );
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return error;
}
CORBA::Long NodeID2OfSide1ToMerge,
CORBA::Long NodeID2OfSide2ToMerge)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
SMESHDS_Mesh* aMesh = GetMeshDS();
!aSecondNode2ToMerge)
return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
- map<int,const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
+ TIDSortedElemSet aSide1Elems, aSide2Elems;
ToMap(IDsOfSide1Elements, aMesh, aSide1Elems);
ToMap(IDsOfSide2Elements, aMesh, aSide2Elems);
<< NodeID2OfSide1ToMerge << ", "
<< NodeID2OfSide2ToMerge << ")";
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
aFirstNode1ToMerge,
aSecondNode1ToMerge,
aSecondNode2ToMerge));
- UpdateLastResult(anEditor);
+ StoreResult(anEditor);
return error;
}
CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
const SMESH::long_array& newIDs)
{
- myLastCreatedElems = new SMESH::long_array();
- myLastCreatedNodes = new SMESH::long_array();
+ initData();
const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
if(!elem) return false;
//================================================================================
/*!
- * \brief Update myLastCreatedNodes and myLastCreatedElems
+ * \brief Update myLastCreated* or myPreviewData
* \param anEditor - it contains last modification results
*/
//================================================================================
-void SMESH_MeshEditor_i::UpdateLastResult(::SMESH_MeshEditor& anEditor)
+void SMESH_MeshEditor_i::StoreResult(::SMESH_MeshEditor& anEditor)
{
- // add new elements into myLastCreatedNodes
- SMESH_SequenceOfElemPtr aSeq = anEditor.GetLastCreatedNodes();
- SMESH::long_array_var aResult = new SMESH::long_array;
- aResult->length(aSeq.Length());
- int i=0;
- for(; i<aSeq.Length(); i++) {
- aResult[i] = aSeq.Value(i+1)->GetID();
+ if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
+
+ list<int> aNodesConnectivity;
+ typedef map<int, int> TNodesMap;
+ TNodesMap nodesMap;
+
+ TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
+ SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
+
+ SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
+ int nbEdges = aMeshDS->NbEdges();
+ int nbFaces = aMeshDS->NbFaces();
+ int nbVolum = aMeshDS->NbVolumes();
+ switch ( previewType ) {
+ case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
+ case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
+ case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
+ default:;
+ }
+ myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
+ myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
+ int i = 0, j = 0;
+ SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
+
+ while ( itMeshElems->more() ) {
+ const SMDS_MeshElement* aMeshElem = itMeshElems->next();
+ if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
+ continue;
+
+ SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
+ while ( itElemNodes->more() ) {
+ const SMDS_MeshNode* aMeshNode =
+ static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
+ int aNodeID = aMeshNode->GetID();
+ TNodesMap::iterator anIter = nodesMap.find(aNodeID);
+ if ( anIter == nodesMap.end() ) {
+ // filling the nodes coordinates
+ myPreviewData->nodesXYZ[j].x = aMeshNode->X();
+ myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
+ myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
+ anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
+ j++;
+ }
+ aNodesConnectivity.push_back(anIter->second);
+ }
+
+ // filling the elements types
+ SMDSAbs_ElementType aType;
+ bool isPoly;
+ /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
+ aType = SMDSAbs_Node;
+ isPoly = false;
+ }
+ else*/ {
+ aType = aMeshElem->GetType();
+ isPoly = aMeshElem->IsPoly();
+ }
+
+ myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
+ myPreviewData->elementTypes[i].isPoly = isPoly;
+ myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
+ i++;
+
+ }
+ myPreviewData->nodesXYZ.length( j );
+
+ // filling the elements connectivities
+ list<int>::iterator aConnIter = aNodesConnectivity.begin();
+ myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
+ for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
+ myPreviewData->elementConnectivities[i] = *aConnIter;
+
+ return;
+ }
+
+ {
+ // add new nodes into myLastCreatedNodes
+ const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
+ myLastCreatedNodes->length(aSeq.Length());
+ for(int i=0; i<aSeq.Length(); i++)
+ myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
}
- myLastCreatedNodes = aResult._retn();
- // add new elements into myLastCreatedElems
- aSeq = anEditor.GetLastCreatedElems();
- aResult = new SMESH::long_array;
- aResult->length(aSeq.Length());
- i=0;
- for(; i<aSeq.Length(); i++) {
- aResult[i] = aSeq.Value(i+1)->GetID();
+ {
+ // add new elements into myLastCreatedElems
+ const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
+ myLastCreatedElems->length(aSeq.Length());
+ for(int i=0; i<aSeq.Length(); i++)
+ myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
}
- myLastCreatedElems = aResult._retn();
+}
+
+//================================================================================
+/*!
+ * Return data of mesh edition preview
+ */
+//================================================================================
+
+SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
+{
+ return myPreviewData._retn();
}
//================================================================================
SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
{
- return myLastCreatedNodes;
+ return myLastCreatedNodes._retn();
}
//================================================================================
SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
{
- return myLastCreatedElems;
+ return myLastCreatedElems._retn();
}
-
//=======================================================================
//function : ConvertToQuadratic
//purpose :
void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
{
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
anEditor.ConvertToQuadratic(theForce3d);
// Update Python script
- TPythonDump() << this << ".ConvertToQuadratic( "
- << theForce3d << " )";
+ TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
}
//=======================================================================
CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
{
- ::SMESH_MeshEditor anEditor( _myMesh );
+ ::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
// Update Python script
TPythonDump() << this << ".ConvertFromQuadratic()";
#include "SMESH.hxx"
#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
#include "SMESH_Mesh.hxx"
class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
{
public:
- SMESH_MeshEditor_i(SMESH_Mesh * theMesh);
+ SMESH_MeshEditor_i(SMESH_Mesh * theMesh, bool isPreview);
- virtual ~ SMESH_MeshEditor_i()
- {
- };
+ virtual ~ SMESH_MeshEditor_i();
// --- CORBA
CORBA::Boolean RemoveElements(const SMESH::long_array & IDsOfElements);
CORBA::Boolean HasRefPoint,
const SMESH::PointStruct & RefPoint);
+ SMESH::double_array* LinearAnglesVariation(SMESH::SMESH_Mesh_ptr PathMesh,
+ GEOM::GEOM_Object_ptr PathShape,
+ const SMESH::double_array & Angles);
+
void Mirror(const SMESH::long_array & IDsOfElements,
const SMESH::AxisStruct & Axis,
SMESH::SMESH_MeshEditor::MirrorType MirrorType,
void FindCoincidentNodes (CORBA::Double Tolerance,
SMESH::array_of_long_array_out GroupsOfNodes);
+ void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
+ CORBA::Double Tolerance,
+ SMESH::array_of_long_array_out GroupsOfNodes);
void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes);
+ void FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
+ SMESH::array_of_long_array_out GroupsOfElementsID);
+ void MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID);
void MergeEqualElements();
+ CORBA::Long MoveClosestNodeToPoint(CORBA::Double x,
+ CORBA::Double y,
+ CORBA::Double z,
+ CORBA::Long nodeID);
+
SMESH::SMESH_MeshEditor::Sew_Error
*/
CORBA::Boolean ChangeElemNodes(CORBA::Long ide, const SMESH::long_array& newIDs);
+ /*!
+ * Return data of mesh edition preview
+ */
+ SMESH::MeshPreviewStruct* GetPreviewData();
+
/*!
* If during last operation of MeshEditor some nodes were
* created this method returns list of it's IDs, if new nodes
//
/*!
- * \brief Update myLastCreatedNodes and myLastCreatedElems
+ * \brief Update myLastCreated* or myPreviewData
* \param anEditor - it contains edition results
*/
- void UpdateLastResult(::SMESH_MeshEditor& anEditor);
+ void StoreResult(::SMESH_MeshEditor& anEditor);
/*!
* \brief Return edited mesh ID
* \retval int - mesh ID
*/
- int GetMeshId() const { return _myMesh->GetId(); }
+ int GetMeshId() const { return myMesh->GetId(); }
private:
- SMESHDS_Mesh * GetMeshDS() { return _myMesh->GetMeshDS(); }
- SMESH_Mesh *_myMesh;
- SMESH::long_array* myLastCreatedElems;
- SMESH::long_array* myLastCreatedNodes;
+
+ SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
+ void initData();
+
+ SMESH_Mesh * myMesh;
+
+ SMESH::long_array_var myLastCreatedElems;
+ SMESH::long_array_var myLastCreatedNodes;
+
+ SMESH::MeshPreviewStruct_var myPreviewData;
+ bool myPreviewMode;
};
#endif
CORBA::Long studyId )
: SALOME::GenericObj_i( thePOA )
{
- INFOS("SMESH_Mesh_i");
+ MESSAGE("SMESH_Mesh_i");
_impl = NULL;
_gen_i = gen_i;
_id = myIdGenerator++;
}
}
+//================================================================================
+/*!
+ * \brief return true if mesh has a shape to build a shape on
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
+ throw (SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ bool res = false;
+ try {
+ res = _impl->HasShapeToMesh();
+ }
+ catch(SALOME_Exception & S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+ return res;
+}
+
//=======================================================================
//function : GetShapeToMesh
//purpose :
*/
//=============================================================================
-static SMESH::Hypothesis_Status ConvertHypothesisStatus
+#define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
+
+SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
(SMESH_Hypothesis::Hypothesis_Status theStatus)
{
- SMESH::Hypothesis_Status res;
- switch (theStatus)
- {
- case SMESH_Hypothesis::HYP_OK:
- res = SMESH::HYP_OK; break;
- case SMESH_Hypothesis::HYP_MISSING:
- res = SMESH::HYP_MISSING; break;
- case SMESH_Hypothesis::HYP_CONCURENT:
- res = SMESH::HYP_CONCURENT; break;
- case SMESH_Hypothesis::HYP_BAD_PARAMETER:
- res = SMESH::HYP_BAD_PARAMETER; break;
- case SMESH_Hypothesis::HYP_INCOMPATIBLE:
- res = SMESH::HYP_INCOMPATIBLE; break;
- case SMESH_Hypothesis::HYP_NOTCONFORM:
- res = SMESH::HYP_NOTCONFORM; break;
- case SMESH_Hypothesis::HYP_ALREADY_EXIST:
- res = SMESH::HYP_ALREADY_EXIST; break;
- case SMESH_Hypothesis::HYP_BAD_DIM:
- res = SMESH::HYP_BAD_DIM; break;
- case SMESH_Hypothesis::HYP_BAD_SUBSHAPE:
- res = SMESH::HYP_BAD_SUBSHAPE; break;
- case SMESH_Hypothesis::HYP_BAD_GEOMETRY:
- res = SMESH::HYP_BAD_GEOMETRY; break;
- default:
- res = SMESH::HYP_UNKNOWN_FATAL;
+ switch (theStatus) {
+ RETURNCASE( HYP_OK );
+ RETURNCASE( HYP_MISSING );
+ RETURNCASE( HYP_CONCURENT );
+ RETURNCASE( HYP_BAD_PARAMETER );
+ RETURNCASE( HYP_HIDDEN_ALGO );
+ RETURNCASE( HYP_HIDING_ALGO );
+ RETURNCASE( HYP_UNKNOWN_FATAL );
+ RETURNCASE( HYP_INCOMPATIBLE );
+ RETURNCASE( HYP_NOTCONFORM );
+ RETURNCASE( HYP_ALREADY_EXIST );
+ RETURNCASE( HYP_BAD_DIM );
+ RETURNCASE( HYP_BAD_SUBSHAPE );
+ RETURNCASE( HYP_BAD_GEOMETRY );
+ default:;
}
- return res;
+ return SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
if (MYDEBUG) MESSAGE("GetGroups");
SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
+
// Python Dump
TPythonDump aPythonDump;
- aPythonDump << "[ ";
+ if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
+ aPythonDump << "[ ";
try {
aList->length( _mapGroups.size() );
}
// Update Python script
- aPythonDump << " ] = " << _this() << ".GetGroups()";
+ if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
+ aPythonDump << " ] = " << _this() << ".GetGroups()";
return aList._retn();
}
return *_impl;
}
-
//=============================================================================
/*!
- *
+ * Return mesh editor
*/
//=============================================================================
SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
{
// Create MeshEditor
- SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
+ SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl, false );
SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
// Update Python script
return aMesh._retn();
}
+//=============================================================================
+/*!
+ * Return mesh edition previewer
+ */
+//=============================================================================
+
+SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
+{
+ SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl, true );
+ SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
+ return aMesh._retn();
+}
+
//=============================================================================
/*!
* Export in different formats
*/
//=============================================================================
-CORBA::Long SMESH_Mesh_i::GetMeshPtr()
+CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
{
- return CORBA::Long(size_t(_impl));
+ CORBA::LongLong pointeur = CORBA::LongLong(_impl);
+ cerr << "CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() " << pointeur << endl;
+ return pointeur;
}
void SetShape( GEOM::GEOM_Object_ptr theShapeObject )
throw (SALOME::SALOME_Exception);
+ CORBA::Boolean HasShapeToMesh()
+ throw (SALOME::SALOME_Exception);
+
GEOM::GEOM_Object_ptr GetShapeToMesh()
throw (SALOME::SALOME_Exception);
SMESH::SMESH_MeshEditor_ptr GetMeshEditor();
+ SMESH::SMESH_MeshEditor_ptr GetMeshEditPreviewer();
+
void ClearLog()
throw (SALOME::SALOME_Exception);
SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
SMESH::SMESH_Hypothesis_ptr anHyp);
+ static SMESH::Hypothesis_Status
+ ConvertHypothesisStatus (SMESH_Hypothesis::Hypothesis_Status theStatus);
+
int importMEDFile( const char* theFileName, const char* theMeshName );
SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject );
virtual SMESH::long_array* GetIDs();
- CORBA::Long GetMeshPtr();
+ CORBA::LongLong GetMeshPtr();
/*!
for ( ; sm != smList.end(); ++sm )
{
SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
- while ( eIt->more() ) {
- const SMDS_MeshElement* anElem = eIt->next();
- SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ if ( eIt->more() ) {
+ while ( eIt->more() ) {
+ const SMDS_MeshElement* anElem = eIt->next();
+ SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ while ( nIt->more() )
+ nodeIds.insert( nIt->next()->GetID() );
+ }
+ } else {
+ SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
while ( nIt->more() )
nodeIds.insert( nIt->next()->GetID() );
- }
+ }
}
return nodeIds.size();
}
if ( all ) { // all nodes of submesh elements
SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
- while ( eIt->more() ) {
- const SMDS_MeshElement* anElem = eIt->next();
- SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ if ( eIt->more() ) {
+ while ( eIt->more() ) {
+ const SMDS_MeshElement* anElem = eIt->next();
+ SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ while ( nIt->more() )
+ nodeIds.insert( nIt->next()->GetID() );
+ }
+ } else {
+ SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
while ( nIt->more() )
nodeIds.insert( nIt->next()->GetID() );
}
return nodeIds.size();
}
-
+
return aSubMeshDS->NbNodes();
}
*
*/
//=============================================================================
-
+
SMESH::long_array* SMESH_subMesh_i::GetElementsId()
throw (SALOME::SALOME_Exception)
{
if ( theElemType == SMESH::NODE )
{
SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
- while ( eIt->more() ) {
- const SMDS_MeshElement* anElem = eIt->next();
- SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ if ( eIt->more() ) {
+ while ( eIt->more() ) {
+ const SMDS_MeshElement* anElem = eIt->next();
+ SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ while ( nIt->more() )
+ nodeIds.insert( nIt->next()->GetID() );
+ }
+ } else {
+ SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
while ( nIt->more() )
nodeIds.insert( nIt->next()->GetID() );
}
if ( theElemType == SMESH::NODE && aSubMeshDS )
{
SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
- while ( eIt->more() ) {
- const SMDS_MeshElement* anElem = eIt->next();
- SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ if ( eIt->more() ) {
+ while ( eIt->more() ) {
+ const SMDS_MeshElement* anElem = eIt->next();
+ SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+ while ( nIt->more() )
+ nodeIds.insert( nIt->next()->GetID() );
+ }
+ } else {
+ SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
while ( nIt->more() )
nodeIds.insert( nIt->next()->GetID() );
}
# see salome_shared_modules.py
# (avoids incomplete import at run time)
-print "============== import SMESH ======================="
+from launchConfigureParser import verbose
+
+if verbose(): print "============== import SMESH ======================="
import SMESH
import StdMeshers
+import SALOME
+
# import NETGENPlugin module if possible
noNETGENPlugin = 0
try:
pass
# Types of algo
-REGULAR = 1
-PYTHON = 2
+REGULAR = 1
+PYTHON = 2
+COMPOSITE = 3
MEFISTO = 3
NETGEN = 4
if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
aCriterion.Compare = EnumToLong(Compare)
+ elif Compare == "=" or Compare == "==":
+ aCriterion.Compare = EnumToLong(FT_EqualTo)
+ elif Compare == "<":
+ aCriterion.Compare = EnumToLong(FT_LessThan)
+ elif Compare == ">":
+ aCriterion.Compare = EnumToLong(FT_MoreThan)
else:
aCriterion.Compare = EnumToLong(FT_EqualTo)
aTreshold = Compare
- if CritType in [FT_BelongToGeom, FT_BelongToPlane,
+ if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
FT_BelongToCylinder, FT_LyingOnGeom]:
# Check treshold
if isinstance(aTreshold, geompy.GEOM._objref_GEOM_Object):
print "Error: given parameter is not numerucal functor type."
+## Print error message if a hypothesis was not assigned.
+def TreatHypoStatus(status, hypName, geomName, isAlgo):
+ if isAlgo:
+ hypType = "algorithm"
+ else:
+ hypType = "hypothesis"
+ pass
+ if status == HYP_UNKNOWN_FATAL :
+ reason = "for unknown reason"
+ elif status == HYP_INCOMPATIBLE :
+ reason = "this hypothesis mismatches algorithm"
+ elif status == HYP_NOTCONFORM :
+ reason = "not conform mesh would be built"
+ elif status == HYP_ALREADY_EXIST :
+ reason = hypType + " of the same dimension already assigned to this shape"
+ elif status == HYP_BAD_DIM :
+ reason = hypType + " mismatches shape"
+ elif status == HYP_CONCURENT :
+ reason = "there are concurrent hypotheses on sub-shapes"
+ elif status == HYP_BAD_SUBSHAPE :
+ reason = "shape is neither the main one, nor its subshape, nor a valid group"
+ elif status == HYP_BAD_GEOMETRY:
+ reason = "geometry mismatches algorithm's expectation"
+ elif status == HYP_HIDDEN_ALGO:
+ reason = "it is hidden by an algorithm of upper dimension generating all-dimensions elements"
+ elif status == HYP_HIDING_ALGO:
+ reason = "it hides algorithm(s) of lower dimension by generating all-dimensions elements"
+ else:
+ return
+ hypName = '"' + hypName + '"'
+ geomName= '"' + geomName+ '"'
+ if status < HYP_UNKNOWN_FATAL:
+ print hypName, "was assigned to", geomName,"but", reason
+ else:
+ print hypName, "was not assigned to",geomName,":", reason
+ pass
+
## Mother class to define algorithm, recommended to don't use directly.
def GetId(self):
return self.algo.GetId()
- ## Private method. Print error message if a hypothesis was not assigned.
- def TreatHypoStatus(self, status, hypName, geomName, isAlgo):
- if isAlgo:
- hypType = "algorithm"
- else:
- hypType = "hypothesis"
- if status == HYP_UNKNOWN_FATAL :
- reason = "for unknown reason"
- elif status == HYP_INCOMPATIBLE :
- reason = "this hypothesis mismatches algorithm"
- elif status == HYP_NOTCONFORM :
- reason = "not conform mesh would be built"
- elif status == HYP_ALREADY_EXIST :
- reason = hypType + " of the same dimension already assigned to this shape"
- elif status == HYP_BAD_DIM :
- reason = hypType + " mismatches shape"
- elif status == HYP_CONCURENT :
- reason = "there are concurrent hypotheses on sub-shapes"
- elif status == HYP_BAD_SUBSHAPE :
- reason = "shape is neither the main one, nor its subshape, nor a valid group"
- elif status == HYP_BAD_GEOMETRY:
- reason = "geometry mismatches algorithm's expectation"
- else:
- return
- hypName = '"' + hypName + '"'
- geomName= '"' + geomName+ '"'
- if status < HYP_UNKNOWN_FATAL:
- print hypName, "was assigned to", geomName,"but", reason
- else:
- print hypName, "was not assigned to",geomName,":", reason
- pass
-
## Private method.
def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
if geom is None:
self.algo = smesh.CreateHypothesis(hypo, so)
SetName(self.algo, name + "/" + hypo)
status = mesh.mesh.AddHypothesis(self.geom, self.algo)
- self.TreatHypoStatus( status, hypo, name, 1 )
+ TreatHypoStatus( status, hypo, name, 1 )
## Private method
def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
name = GetName(self.geom)
SetName(hypo, name + "/" + hyp + a)
status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
- self.TreatHypoStatus( status, hyp, name, 0 )
+ TreatHypoStatus( status, hyp, name, 0 )
return hypo
hyp.SetFineness( fineness )
return hyp
+ ## Define "SegmentLengthAroundVertex" hypothesis
+ # @param length for the segment length
+ # @param vertex for the length localization: vertex index [0,1] | verext object
+ def LengthNearVertex(self, length, vertex=0):
+ import types
+ store_geom = self.geom
+ if vertex:
+ if type(vertex) is types.IntType:
+ vertex = geompy.SubShapeAllSorted(self.geom,geompy.ShapeType["VERTEX"])[vertex]
+ pass
+ self.geom = vertex
+ pass
+ hyp = self.Hypothesis("SegmentAroundVertex_0D")
+ hyp = self.Hypothesis("SegmentLengthAroundVertex")
+ self.geom = store_geom
+ hyp.SetLength( length )
+ return hyp
+
## Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
# If the 2D mesher sees that all boundary edges are quadratic ones,
# it generates quadratic faces, else it generates linear faces using
hyp = self.Hypothesis("QuadraticMesh")
return hyp
+# Public class: Mesh_CompositeSegment
+# --------------------------
+
+## Class to define a segment 1D algorithm for discretization
+#
+# More details.
+class Mesh_CompositeSegment(Mesh_Segment):
+
+ ## Private constructor.
+ def __init__(self, mesh, geom=0):
+ self.Create(mesh, geom, "CompositeSegment_1D")
+
+
# Public class: Mesh_Segment_Python
# ---------------------------------
# Public class: Mesh_Prism
# ------------------------
-## Class to define a Prism 3D algorithm
+## Class to define a 3D extrusion algorithm
#
# More details.
class Mesh_Prism3D(Mesh_Algorithm):
return Mesh_Segment(self, geom)
elif algo == PYTHON:
return Mesh_Segment_Python(self, geom)
+ elif algo == COMPOSITE:
+ return Mesh_CompositeSegment(self, geom)
else:
return Mesh_Segment(self, geom)
def Projection3D(self, geom=0):
return Mesh_Projection3D(self, geom)
- ## Creates a Prism 3D or RadialPrism 3D algorithm for solids.
+ ## Creates a 3D extrusion (Prism 3D) or RadialPrism 3D algorithm for solids.
# If the optional \a geom parameter is not sets, this algorithm is global.
# Otherwise, this algorithm define a submesh based on \a geom subshape.
# @param geom If defined, subshape to be meshed
return 0
else:
geom = self.geom
- ok = smesh.Compute(self.mesh, geom)
+ ok = False
+ try:
+ ok = smesh.Compute(self.mesh, geom)
+ except SALOME.SALOME_Exception, ex:
+ print "Mesh computation failed, exception cought:"
+ print " ", ex.details.text
+ except:
+ import traceback
+ print "Mesh computation failed, exception cought:"
+ traceback.print_exc()
if not ok:
errors = smesh.GetAlgoState( self.mesh, geom )
allReasons = ""
allReasons += reason
pass
if allReasons != "":
- print '"' + GetName(self.mesh) + '"',"not computed:"
+ print '"' + GetName(self.mesh) + '"',"has not been computed:"
print allReasons
+ else:
+ print '"' + GetName(self.mesh) + '"',"has not been computed."
pass
pass
if salome.sg.hasDesktop():
smeshgui = salome.ImportComponentGUI("SMESH")
smeshgui.Init(salome.myStudyId)
- smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok )
+ smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
salome.sg.updateObjBrowser(1)
pass
return ok
self.Hexahedron()
pass
return self.Compute()
+
+ ## Assign hypothesis
+ # @param hyp is a hypothesis to assign
+ # @param geom is subhape of mesh geometry
+ def AddHypothesis(self, hyp, geom=0 ):
+ if isinstance( hyp, Mesh_Algorithm ):
+ hyp = hyp.GetAlgorithm()
+ pass
+ if not geom:
+ geom = self.geom
+ pass
+ status = self.mesh.AddHypothesis(geom, hyp)
+ isAlgo = ( hyp._narrow( SMESH.SMESH_Algo ) is not None )
+ TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
+ return status
## Get the list of hypothesis added on a geom
# @param geom is subhape of mesh geometry
## Move node with given id
# @param NodeID id of the node
- # @param x displacing along the X axis
- # @param y displacing along the Y axis
- # @param z displacing along the Z axis
+ # @param x new X coordinate
+ # @param y new Y coordinate
+ # @param z new Z coordinate
def MoveNode(self, NodeID, x, y, z):
return self.editor.MoveNode(NodeID, x, y, z)
+ ## Find a node closest to a point
+ # @param x X coordinate of a point
+ # @param y Y coordinate of a point
+ # @param z Z coordinate of a point
+ # @return id of a node
+ def FindNodeClosestTo(self, x, y, z):
+ preview = self.mesh.GetMeshEditPreviewer()
+ return preview.MoveClosestNodeToPoint(x, y, z, -1)
+
+ ## Find a node closest to a point and move it to a point location
+ # @param x X coordinate of a point
+ # @param y Y coordinate of a point
+ # @param z Z coordinate of a point
+ # @return id of a moved node
+ def MeshToPassThroughAPoint(self, x, y, z):
+ return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
+
## Replace two neighbour triangles sharing Node1-Node2 link
# with ones built on the same 4 nodes but having other common link.
# @param NodeID1 first node id
# diagonal is better, 0 if error occurs.
def BestSplit (self, IDOfQuad, theCriterion):
return self.editor.BestSplit(IDOfQuad, GetFunctor(theCriterion))
+
+ ## Split quafrangle faces near triangular facets of volumes
+ #
+ def SplitQuadsNearTriangularFacets(self):
+ faces_array = self.GetElementsByType(SMESH.FACE)
+ for face_id in faces_array:
+ if self.GetElemNbNodes(face_id) == 4: # quadrangle
+ quad_nodes = self.mesh.GetElemNodes(face_id)
+ node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
+ isVolumeFound = False
+ for node1_elem in node1_elems:
+ if not isVolumeFound:
+ if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
+ nb_nodes = self.GetElemNbNodes(node1_elem)
+ if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
+ volume_elem = node1_elem
+ volume_nodes = self.mesh.GetElemNodes(volume_elem)
+ if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
+ if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
+ isVolumeFound = True
+ if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
+ self.SplitQuad([face_id], False) # diagonal 2-4
+ elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
+ isVolumeFound = True
+ self.SplitQuad([face_id], True) # diagonal 1-3
+ elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
+ if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
+ isVolumeFound = True
+ self.SplitQuad([face_id], True) # diagonal 1-3
+
+ ## @brief Split hexahedrons into tetrahedrons.
+ #
+ # Use pattern mapping functionality for splitting.
+ # @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+ # @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+ # pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+ # will be mapped into <theNode000>-th node of each volume, the (0,0,1)
+ # key-point will be mapped into <theNode001>-th node of each volume.
+ # The (0,0,0) key-point of used pattern corresponds to not split corner.
+ # @param @return TRUE in case of success, FALSE otherwise.
+ def SplitHexaToTetras (self, theObject, theNode000, theNode001):
+ # Pattern: 5.---------.6
+ # /|#* /|
+ # / | #* / |
+ # / | # * / |
+ # / | # /* |
+ # (0,0,1) 4.---------.7 * |
+ # |#* |1 | # *|
+ # | # *.----|---#.2
+ # | #/ * | /
+ # | /# * | /
+ # | / # * | /
+ # |/ #*|/
+ # (0,0,0) 0.---------.3
+ pattern_tetra = "!!! Nb of points: \n 8 \n\
+ !!! Points: \n\
+ 0 0 0 !- 0 \n\
+ 0 1 0 !- 1 \n\
+ 1 1 0 !- 2 \n\
+ 1 0 0 !- 3 \n\
+ 0 0 1 !- 4 \n\
+ 0 1 1 !- 5 \n\
+ 1 1 1 !- 6 \n\
+ 1 0 1 !- 7 \n\
+ !!! Indices of points of 6 tetras: \n\
+ 0 3 4 1 \n\
+ 7 4 3 1 \n\
+ 4 7 5 1 \n\
+ 6 2 5 7 \n\
+ 1 5 2 7 \n\
+ 2 3 1 7 \n"
+
+ pattern = GetPattern()
+ isDone = pattern.LoadFromFile(pattern_tetra)
+ if not isDone:
+ print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+ return isDone
+
+ pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+ isDone = pattern.MakeMesh(self.mesh, False, False)
+ if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+ # split quafrangle faces near triangular facets of volumes
+ self.SplitQuadsNearTriangularFacets()
+
+ return isDone
+
+ ## @brief Split hexahedrons into prisms.
+ #
+ # Use pattern mapping functionality for splitting.
+ # @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+ # @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+ # pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+ # will be mapped into <theNode000>-th node of each volume, the (0,0,1)
+ # key-point will be mapped into <theNode001>-th node of each volume.
+ # The edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
+ # @param @return TRUE in case of success, FALSE otherwise.
+ def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
+ # Pattern: 5.---------.6
+ # /|# /|
+ # / | # / |
+ # / | # / |
+ # / | # / |
+ # (0,0,1) 4.---------.7 |
+ # | | | |
+ # | 1.----|----.2
+ # | / * | /
+ # | / * | /
+ # | / * | /
+ # |/ *|/
+ # (0,0,0) 0.---------.3
+ pattern_prism = "!!! Nb of points: \n 8 \n\
+ !!! Points: \n\
+ 0 0 0 !- 0 \n\
+ 0 1 0 !- 1 \n\
+ 1 1 0 !- 2 \n\
+ 1 0 0 !- 3 \n\
+ 0 0 1 !- 4 \n\
+ 0 1 1 !- 5 \n\
+ 1 1 1 !- 6 \n\
+ 1 0 1 !- 7 \n\
+ !!! Indices of points of 2 prisms: \n\
+ 0 1 3 4 5 7 \n\
+ 2 3 1 6 7 5 \n"
+
+ pattern = GetPattern()
+ isDone = pattern.LoadFromFile(pattern_prism)
+ if not isDone:
+ print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+ return isDone
+
+ pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+ isDone = pattern.MakeMesh(self.mesh, False, False)
+ if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+ # split quafrangle faces near triangular facets of volumes
+ self.SplitQuadsNearTriangularFacets()
+
+ return isDone
## Smooth elements
# @param IDsOfElements list if ids of elements to smooth
# @param HasRefPoint allows to use base point
# @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
# User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+ # @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
- HasAngles, Angles, HasRefPoint, RefPoint):
+ HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation=False):
if IDsOfElements == []:
IDsOfElements = self.GetElementsId()
if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
- RefPoint = GetPointStruct(RefPoint)
+ RefPoint = GetPointStruct(RefPoint)
+ pass
return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh.GetMesh(), PathShape, NodeStart,
HasAngles, Angles, HasRefPoint, RefPoint)
# @param HasRefPoint allows to use base point
# @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
# User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+ # @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
- HasAngles, Angles, HasRefPoint, RefPoint):
+ HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation=False):
if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
RefPoint = GetPointStruct(RefPoint)
return self.editor.ExtrusionAlongPathObject(theObject, PathMesh.GetMesh(), PathShape, NodeStart,
- HasAngles, Angles, HasRefPoint, RefPoint)
+ HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation)
## Symmetrical copy of mesh elements
# @param IDsOfElements list of elements ids
def FindCoincidentNodes (self, Tolerance):
return self.editor.FindCoincidentNodes(Tolerance)
+ ## Find group of nodes close to each other within Tolerance.
+ # @param Tolerance tolerance value
+ # @param SubMeshOrGroup SubMesh or Group
+ # @param list of group of nodes
+ def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance):
+ return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance)
+
## Merge nodes
# @param list of group of nodes
def MergeNodes (self, GroupsOfNodes):
self.editor.MergeNodes(GroupsOfNodes)
+ ## Find elements built on the same nodes.
+ # @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
+ # @return a list of groups of equal elements
+ def FindEqualElements (self, MeshOrSubMeshOrGroup):
+ return self.editor.FindEqualElements(MeshOrSubMeshOrGroup)
+
+ ## Merge elements in each given group.
+ # @param GroupsOfElementsID groups of elements for merging
+ def MergeElements(self, GroupsOfElementsID):
+ self.editor.MergeElements(GroupsOfElementsID)
+
## Remove all but one of elements built on the same nodes.
def MergeEqualElements(self):
self.editor.MergeEqualElements()
StdMeshers_RadialPrism_3D.hxx \
StdMeshers_ProjectionUtils.hxx \
StdMeshers_LayerDistribution.hxx \
+ StdMeshers_CompositeSegment_1D.hxx \
+ StdMeshers_FaceSide.hxx \
+ StdMeshers_SegmentAroundVertex_0D.hxx \
+ StdMeshers_SegmentLengthAroundVertex_0D.hxx \
SMESH_StdMeshers.hxx
# Libraries targets
StdMeshers_Projection_3D.cxx \
StdMeshers_RadialPrism_3D.cxx \
StdMeshers_ProjectionUtils.cxx \
- StdMeshers_LayerDistribution.cxx
+ StdMeshers_LayerDistribution.cxx \
+ StdMeshers_CompositeSegment_1D.cxx \
+ StdMeshers_FaceSide.cxx \
+ StdMeshers_SegmentAroundVertex_0D.cxx \
+ StdMeshers_SegmentLengthAroundVertex_0D.cxx
# additionnal information to compil and link file
libStdMeshers_la_CPPFLAGS = \
}
}
-//================================================================================
-/*!
- * \brief Return pointer to TopoDS_TShape
- * \param theShape - The TopoDS_Shape
- * \retval inline const TopoDS_TShape* - result
- */
-//================================================================================
+namespace {
-inline const TopoDS_TShape* getTShape(const TopoDS_Shape& theShape)
-{
- return theShape.TShape().operator->();
-}
-//================================================================================
-/*!
- * \brief Compute segment length for all edges
- * \param theMesh - The mesh
- * \param theTShapeToLengthMap - The map of edge to segment length
- */
-//================================================================================
-
-static void computeLengths( SMESHDS_Mesh* aMesh,
- map<const TopoDS_TShape*, double> & theTShapeToLengthMap)
-{
- theTShapeToLengthMap.clear();
-
- TopoDS_Shape aMainShape = aMesh->ShapeToMesh();
+ //================================================================================
+ /*!
+ * \brief Return pointer to TopoDS_TShape
+ * \param theShape - The TopoDS_Shape
+ * \retval inline const TopoDS_TShape* - result
+ */
+ //================================================================================
- // Find length of longest and shortest edge
- double Lmin = DBL_MAX, Lmax = -DBL_MAX;
- TopTools_IndexedMapOfShape edgeMap;
- TopExp::MapShapes( aMainShape, TopAbs_EDGE, edgeMap);
- for ( int i = 1; i <= edgeMap.Extent(); ++i )
+ inline const TopoDS_TShape* getTShape(const TopoDS_Shape& theShape)
{
- TopoDS_Edge edge = TopoDS::Edge( edgeMap(i) );
- //if ( BRep_Tool::Degenerated( edge )) continue;
-
- Standard_Real L = SMESH_Algo::EdgeLength( edge );
- if ( L < DBL_MIN ) continue;
-
- if ( L > Lmax ) Lmax = L;
- if ( L < Lmin ) Lmin = L;
-
- // remember i-th edge length
- theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L ));
+ return theShape.TShape().operator->();
}
- // Compute S0
-
- // image attached to PAL10237
-
-// NbSeg
-// ^
-// |
-// 10|\
-// | \
-// | \
-// | \
-// 5| --------
-// |
-// +------------>
-// 1 10 Lmax/Lmin
+ //================================================================================
+ /*!
+ * \brief computes segment length by S0 and edge length
+ */
+ //================================================================================
- const int NbSegMin = 5, NbSegMax = 10; // on axis NbSeg
- const double Lrat1 = 1., Lrat2 = 10.; // on axis Lmax/Lmin
+ const double a14divPI = 14. / PI;
- double Lratio = Lmax/Lmin;
- double NbSeg = NbSegMin;
- if ( Lratio < Lrat2 )
- NbSeg += ( Lrat2 - Lratio ) / ( Lrat2 - Lrat1 ) * ( NbSegMax - NbSegMin );
+ inline double segLength(double S0, double edgeLen, double minLen )
+ {
+ // PAL10237
+ // S = S0 * f(L/Lmin) where f(x) = 1 + (2/Pi * 7 * atan(x/5) )
+ // =>
+ // S = S0 * ( 1 + 14/PI * atan( L / ( 5 * Lmin )))
+ return S0 * ( 1. + a14divPI * atan( edgeLen / ( 5 * minLen )));
+ }
- double S0 = Lmin / (int) NbSeg;
- MESSAGE( "S0 = " << S0 << ", Lmin = " << Lmin << ", Nbseg = " << (int) NbSeg);
+ //================================================================================
+ /*!
+ * \brief Compute segment length for all edges
+ * \param theMesh - The mesh
+ * \param theTShapeToLengthMap - The map of edge to segment length
+ */
+ //================================================================================
+
+ void computeLengths( SMESHDS_Mesh* aMesh,
+ map<const TopoDS_TShape*, double> & theTShapeToLengthMap,
+ double & theS0,
+ double & theMinLen)
+ {
+ theTShapeToLengthMap.clear();
+
+ TopoDS_Shape aMainShape = aMesh->ShapeToMesh();
+
+ // Find length of longest and shortest edge
+ double Lmin = DBL_MAX, Lmax = -DBL_MAX;
+ TopTools_IndexedMapOfShape edgeMap;
+ TopExp::MapShapes( aMainShape, TopAbs_EDGE, edgeMap);
+ for ( int i = 1; i <= edgeMap.Extent(); ++i )
+ {
+ TopoDS_Edge edge = TopoDS::Edge( edgeMap(i) );
+ //if ( BRep_Tool::Degenerated( edge )) continue;
+
+ Standard_Real L = SMESH_Algo::EdgeLength( edge );
+ if ( L < DBL_MIN ) continue;
+
+ if ( L > Lmax ) Lmax = L;
+ if ( L < Lmin ) Lmin = L;
+
+ // remember i-th edge length
+ theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L ));
+ }
+
+ // Compute S0
+
+ // image attached to PAL10237
+
+ // NbSeg
+ // ^
+ // |
+ // 10|\
+ // | \
+ // | \
+ // | \
+ // 5| --------
+ // |
+ // +------------>
+ // 1 10 Lmax/Lmin
+
+ const int NbSegMin = 5, NbSegMax = 10; // on axis NbSeg
+ const double Lrat1 = 1., Lrat2 = 10.; // on axis Lmax/Lmin
+
+ double Lratio = Lmax/Lmin;
+ double NbSeg = NbSegMin;
+ if ( Lratio < Lrat2 )
+ NbSeg += ( Lrat2 - Lratio ) / ( Lrat2 - Lrat1 ) * ( NbSegMax - NbSegMin );
+
+ double S0 = Lmin / (int) NbSeg;
+ MESSAGE( "S0 = " << S0 << ", Lmin = " << Lmin << ", Nbseg = " << (int) NbSeg);
+
+ // Compute segments length for all edges
+ map<const TopoDS_TShape*, double>::iterator tshape_length = theTShapeToLengthMap.begin();
+ for ( ; tshape_length != theTShapeToLengthMap.end(); ++tshape_length )
+ {
+ double & L = tshape_length->second;
+ L = segLength( S0, L, Lmin );
+ }
+ theS0 = S0;
+ theMinLen = Lmin;
+ }
+}
- // Compute segments length for all edges
+//=============================================================================
+/*!
+ * \brief Computes segment length for an edge of given length
+ */
+//=============================================================================
- // S = S0 * f(L/Lmin) where f(x) = 1 + (2/Pi * 7 * atan(x/5) )
- // =>
- // S = S0 * ( 1 + 14/PI * atan( L / ( 5 * Lmin )))
+double StdMeshers_AutomaticLength::GetLength(const SMESH_Mesh* theMesh,
+ const double theEdgeLength)
+ throw(SALOME_Exception)
+{
+ if ( !theMesh ) throw SALOME_Exception(LOCALIZED("NULL Mesh"));
- const double a14divPI = 14. / PI, a5xLmin = 5 * Lmin;
- map<const TopoDS_TShape*, double>::iterator tshape_length = theTShapeToLengthMap.begin();
- for ( ; tshape_length != theTShapeToLengthMap.end(); ++tshape_length )
+ SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
+ if ( theMesh != _mesh )
{
- double & L = tshape_length->second;
- L = S0 * ( 1. + a14divPI * atan( L / a5xLmin ));
+ computeLengths( aMeshDS, _TShapeToLength, _S0, _minLen );
+ _mesh = theMesh;
}
+ double L = segLength( _S0, theEdgeLength, _minLen );
+ return L / (theCoarseConst + theFineConst * _fineness);
}
//=============================================================================
if ( theMesh != _mesh )
{
SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
- computeLengths( aMeshDS, _TShapeToLength );
+ computeLengths( aMeshDS, _TShapeToLength, _S0, _minLen );
_mesh = theMesh;
}
StdMeshers_AutomaticLength(int hypId, int studyId, SMESH_Gen * gen);
virtual ~ StdMeshers_AutomaticLength();
+ /*!
+ * \brief Computes segment for a given edge
+ */
double GetLength(const SMESH_Mesh* aMesh, const TopoDS_Shape& anEdge)
throw(SALOME_Exception);
+ /*!
+ * \brief Computes segment length for an edge of given length
+ */
+ double GetLength(const SMESH_Mesh* aMesh, const double edgeLength)
+ throw(SALOME_Exception);
+
/*!
* \brief Set Fineness
* \param theFineness - The Fineness value [0.0-1.0],
protected:
std::map<const TopoDS_TShape*, double> _TShapeToLength;
const SMESH_Mesh* _mesh;
- double _fineness;
+ double _fineness, _S0, _minLen;
};
#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_Regular_1D.cxx
+// Moved here from SMESH_Regular_1D.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#include "StdMeshers_CompositeSegment_1D.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_AutomaticLength.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_CompCurve.hxx>
+#include <BRep_Builder.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Pnt.hxx>
+
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+
+typedef SMESH_Comment TComm;
+
+using namespace std;
+
+
+namespace {
+
+ //================================================================================
+ /*!
+ * \brief Search for an edge conjunct to the given one by the vertex
+ * Return NULL if more than 2 edges share the vertex or edges
+ * continuity is less than C1
+ */
+ //================================================================================
+
+ TopoDS_Edge nextC1Edge(const TopoDS_Edge& edge,
+ SMESH_Mesh & aMesh,
+ const bool forward)
+ {
+ TopoDS_Edge eNext;
+ TopTools_MapOfShape edgeCounter;
+ edgeCounter.Add( edge );
+ TopoDS_Vertex v;
+ v = forward ? TopExp::LastVertex( edge,1 ) : TopExp::FirstVertex( edge,1 );
+ TopTools_ListIteratorOfListOfShape ancestIt = aMesh.GetAncestors( v );
+ for ( ; ancestIt.More(); ancestIt.Next() )
+ {
+ const TopoDS_Shape & ancestor = ancestIt.Value();
+ if ( ancestor.ShapeType() == TopAbs_EDGE && edgeCounter.Add( ancestor ))
+ eNext = TopoDS::Edge( ancestor );
+ }
+ if ( edgeCounter.Extent() < 3 && !eNext.IsNull() ) {
+ GeomAbs_Shape cont = SMESH_Algo::Continuity( edge, eNext );
+ if (cont >= GeomAbs_G1) {
+ // care of orientation
+ bool reverse;
+ if ( forward )
+ reverse = ( !v.IsSame( TopExp::FirstVertex( eNext, true )));
+ else
+ reverse = ( !v.IsSame( TopExp::LastVertex( eNext, true )));
+ if ( reverse )
+ eNext.Reverse();
+ return eNext;
+ }
+ }
+ return TopoDS_Edge();
+ }
+
+ //================================================================================
+ /*!
+ * \brief Update submeshes state for all edges and internal vertices,
+ * make them look computed even if none edge or node is set on them
+ */
+ //================================================================================
+
+ void careOfSubMeshes( StdMeshers_FaceSide& side, EventListener* eListener)
+ {
+ if ( side.NbEdges() < 2)
+ return;
+ for ( int iE = 0; iE < side.NbEdges(); ++iE )
+ {
+ // set listener and its data
+ EventListenerData * listenerData = new EventListenerData(true);
+ const TopoDS_Edge& edge = side.Edge( iE );
+ SMESH_subMesh * sm = side.GetMesh()->GetSubMesh( edge );
+ sm->SetEventListener( eListener, listenerData, sm );
+ // add edge submesh to the data
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ if ( !sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK ) {
+ sm->SetIsAlwaysComputed( true );
+ listenerData->mySubMeshes.push_back( sm );
+ }
+ // add internal vertex submesh to the data
+ if ( iE )
+ {
+ TopoDS_Vertex V = side.FirstVertex( iE );
+ sm = side.GetMesh()->GetSubMesh( V );
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ if ( !sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK )
+ sm->SetIsAlwaysComputed( true );
+ listenerData->mySubMeshes.push_back( sm );
+ }
+ }
+ }
+
+ //================================================================================
+ /*!
+ * \brief Class used to restore nodes on internal vertices of a complex side
+ * when StdMeshers_CompositeSegment_1D algorithm is removed
+ */
+ //================================================================================
+
+ struct VertexNodesRestoringListener : public SMESH_subMeshEventListener
+ {
+ VertexNodesRestoringListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+ {}
+ /*!
+ * \brief Restore nodes on internal vertices of a complex side
+ * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+ * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+ * \param subMesh - the submesh where the event occures
+ * \param data - listener data stored in the subMesh
+ * \param hyp - hypothesis, if eventType is algo_event
+ */
+ void ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ EventListenerData* data,
+ const SMESH_Hypothesis* /*hyp*/)
+ {
+ bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT &&
+ subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK );
+ if ( hypRemoved && data )
+ {
+ list<SMESH_subMesh*>::iterator smIt = data->mySubMeshes.begin();
+ for ( ; smIt != data->mySubMeshes.end(); ++smIt )
+ {
+ if ( SMESH_subMesh* sm = *smIt ) {
+ sm->SetIsAlwaysComputed( false );
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ }
+ }
+ // at study restoration:
+ // check if edge submesh must have _alwaysComputed flag
+ else if ( event == SMESH_subMesh::SUBMESH_RESTORED &&
+ eventType == SMESH_subMesh::COMPUTE_EVENT )
+ {
+ if ( !subMesh->GetEventListenerData( this )) { // not yet checked
+ SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
+ if ( meshDS->NbNodes() > 0 ) {
+ // check if there are nodes on all vertices
+ bool hasNodesOnVerext = true;
+ SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+ while ( hasNodesOnVerext && smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ hasNodesOnVerext = ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbNodes() );
+ }
+ if ( !hasNodesOnVerext ) {
+ // check if an edge is a part of a complex side
+ TopoDS_Face face;
+ TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() );
+ auto_ptr< StdMeshers_FaceSide > side
+ ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),
+ edge, face, false ));
+ if ( side->NbEdges() > 1 && side->NbSegments() )
+ careOfSubMeshes( *side, this );
+ }
+ }
+ }
+ }
+ }
+ }; // struct VertexNodesRestoringListener
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D(int hypId,
+ int studyId,
+ SMESH_Gen * gen)
+ :StdMeshers_Regular_1D(hypId, studyId, gen)
+{
+ MESSAGE("StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D");
+ _name = "CompositeSegment_1D";
+ _EventListener = new VertexNodesRestoringListener();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D::~StdMeshers_CompositeSegment_1D()
+{
+ delete _EventListener;
+}
+
+//=============================================================================
+/*!
+ * \brief Sets event listener to submeshes if necessary
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//=============================================================================
+
+void StdMeshers_CompositeSegment_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+ subMesh->SetEventListener( _EventListener, 0, subMesh);
+ StdMeshers_Regular_1D::SetEventListener( subMesh );
+}
+
+//=============================================================================
+/*!
+ * \brief Return a face side the edge belongs to
+ */
+//=============================================================================
+
+StdMeshers_FaceSide *
+StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh& aMesh,
+ const TopoDS_Edge& anEdge,
+ const TopoDS_Face& aFace,
+ const bool ignoreMeshed)
+{
+ list< TopoDS_Edge > edges;
+ edges.push_back( anEdge );
+
+ list <const SMESHDS_Hypothesis *> hypList;
+ SMESH_Algo* theAlgo = aMesh.GetGen()->GetAlgo( aMesh, anEdge );
+ if ( theAlgo ) hypList = theAlgo->GetUsedHypothesis(aMesh, anEdge, false);
+ for ( int forward = 0; forward < 2; ++forward )
+ {
+ TopoDS_Edge eNext = nextC1Edge( anEdge, aMesh, forward );
+ while ( !eNext.IsNull() ) {
+ if ( ignoreMeshed ) {
+ // eNext must not have computed mesh
+ if ( SMESHDS_SubMesh* sm = aMesh.GetMeshDS()->MeshElements(eNext) )
+ if ( sm->NbNodes() || sm->NbElements() )
+ break;
+ }
+ // eNext must have same hypotheses
+ SMESH_Algo* algo = aMesh.GetGen()->GetAlgo( aMesh, eNext );
+ if ( !algo ||
+ string(theAlgo->GetName()) != algo->GetName() ||
+ hypList != algo->GetUsedHypothesis(aMesh, eNext, false))
+ break;
+ if ( forward )
+ edges.push_back( eNext );
+ else
+ edges.push_front( eNext );
+ eNext = nextC1Edge( eNext, aMesh, forward );
+ }
+ }
+ return new StdMeshers_FaceSide( aFace, edges, &aMesh, true, false );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)
+{
+ TopoDS_Edge edge = TopoDS::Edge( aShape );
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+ // Get edges to be discretized as a whole
+ TopoDS_Face nullFace;
+ auto_ptr< StdMeshers_FaceSide > side( GetFaceSide(aMesh, edge, nullFace, true ));
+ //side->dump("IN COMPOSITE SEG");
+
+ if ( side->NbEdges() < 2 )
+ return StdMeshers_Regular_1D::Compute( aMesh, aShape );
+
+ // update segment lenght computed by StdMeshers_AutomaticLength
+ const list <const SMESHDS_Hypothesis * > & hyps = GetUsedHypothesis(aMesh, aShape);
+ if ( !hyps.empty() ) {
+ StdMeshers_AutomaticLength * autoLenHyp = const_cast<StdMeshers_AutomaticLength *>
+ (dynamic_cast <const StdMeshers_AutomaticLength * >(hyps.front()));
+ if ( autoLenHyp )
+ _value[ BEG_LENGTH_IND ]= autoLenHyp->GetLength( &aMesh, side->Length() );
+ }
+
+ // Compute node parameters
+ auto_ptr< BRepAdaptor_CompCurve > C3d ( side->GetCurve3d() );
+ double f = C3d->FirstParameter(), l = C3d->LastParameter();
+ list< double > params;
+ if ( !computeInternalParameters ( *C3d, side->Length(), f, l, params, false ))
+ return false;
+
+ // Redistribute parameters near ends
+ TopoDS_Vertex VFirst = side->FirstVertex();
+ TopoDS_Vertex VLast = side->LastVertex();
+ redistributeNearVertices( aMesh, *C3d, side->Length(), params, VFirst, VLast );
+
+ params.push_front(f);
+ params.push_back(l);
+ int nbNodes = params.size();
+
+ // Create mesh
+
+ const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
+ const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS );
+ if (!nFirst)
+ return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+ <<meshDS->ShapeToIndex(VFirst));
+ if (!nLast)
+ return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+ <<meshDS->ShapeToIndex(VLast));
+
+ vector<const SMDS_MeshNode*> nodes( nbNodes, (const SMDS_MeshNode*)0 );
+ nodes.front() = nFirst;
+ nodes.back() = nLast;
+
+ // create internal nodes
+ list< double >::iterator parIt = params.begin();
+ double prevPar = *parIt;
+ Standard_Real u;
+ for ( int iN = 0; parIt != params.end(); ++iN, ++parIt)
+ {
+ if ( !nodes[ iN ] ) {
+ gp_Pnt p = C3d->Value( *parIt );
+ SMDS_MeshNode* n = meshDS->AddNode( p.X(), p.Y(), p.Z());
+ C3d->Edge( *parIt, edge, u );
+ meshDS->SetNodeOnEdge( n, edge, u );
+// cout << "new NODE: par="<<*parIt<<" ePar="<<u<<" e="<<edge.TShape().operator->()
+// << " " << n << endl;
+ nodes[ iN ] = n;
+ }
+ // create edges
+ if ( iN ) {
+ double mPar = ( prevPar + *parIt )/2;
+ if ( _quadraticMesh ) {
+ // create medium node
+ double segLen = GCPnts_AbscissaPoint::Length(*C3d, prevPar, *parIt);
+ GCPnts_AbscissaPoint ruler( *C3d, segLen/2., prevPar );
+ if ( ruler.IsDone() )
+ mPar = ruler.Parameter();
+ gp_Pnt p = C3d->Value( mPar );
+ SMDS_MeshNode* n = meshDS->AddNode( p.X(), p.Y(), p.Z());
+ //cout << "new NODE "<< n << endl;
+ meshDS->SetNodeOnEdge( n, edge, u );
+ SMDS_MeshEdge * seg = meshDS->AddEdge(nodes[ iN-1 ], nodes[ iN ], n);
+ meshDS->SetMeshElementOnShape(seg, edge);
+ }
+ else {
+ C3d->Edge( mPar, edge, u );
+ SMDS_MeshEdge * seg = meshDS->AddEdge(nodes[ iN-1 ], nodes[ iN ]);
+ meshDS->SetMeshElementOnShape(seg, edge);
+ }
+ }
+ prevPar = *parIt;
+ }
+
+ // remove nodes on internal vertices
+ for ( int iE = 1; iE < side->NbEdges(); ++iE )
+ {
+ TopoDS_Vertex V = side->FirstVertex( iE );
+ while ( const SMDS_MeshNode * n = SMESH_Algo::VertexNode( V, meshDS ))
+ meshDS->RemoveNode( n );
+ }
+
+ // Update submeshes state for all edges and internal vertices,
+ // make them look computed even if none edge or node is set on them
+ careOfSubMeshes( *side, _EventListener );
+
+ return true;
+}
+
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_CompositeSegment_1D.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_CompositeSegment_1D_HXX_
+#define _SMESH_CompositeSegment_1D_HXX_
+
+#include "StdMeshers_Regular_1D.hxx"
+
+class SMESH_subMeshEventListener;
+class SMESH_Mesh;
+class StdMeshers_FaceSide;
+class TopoDS_Edge;
+class TopoDS_Face;
+
+class StdMeshers_CompositeSegment_1D: public StdMeshers_Regular_1D
+{
+public:
+ StdMeshers_CompositeSegment_1D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_CompositeSegment_1D();
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape);
+ /*!
+ * \brief Sets event listener to submeshes if necessary
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+ virtual void SetEventListener(SMESH_subMesh* subMesh);
+
+ /*!
+ * \brief Return a face side the edge belongs to
+ */
+ static StdMeshers_FaceSide * GetFaceSide(SMESH_Mesh& aMesh,
+ const TopoDS_Edge& anEdge,
+ const TopoDS_Face& aFace,
+ const bool ignoreMeshed);
+
+protected:
+ SMESH_subMeshEventListener* _EventListener;
+};
+
+#endif
if( !findBounds( t, i1, i2 ) )
return false;
+ if( i1==i2 ) {
+ f = myData[ 2*i1+1 ];
+ Function::value( t, f );
+ return true;
+ }
+
double
x1 = myData[2*i1], y1 = myData[2*i1+1],
x2 = myData[2*i2], y2 = myData[2*i2+1];
{
double f1,f2, res = 0.0;
if( value( myData[2*i]+d, f1 ) )
- if(!value(myData[2*i], f2))
+ if(!value(myData[2*i], f2)) {
f2 = myData[2*i+1];
+ Function::value( 1, f2 );
+ }
res = (f2+f1) * d / 2.0;
return res;
}
}
for( int i=0; i<n-1; i++ )
- if( myData[2*i]<=x && x<=myData[2*(i+1)] )
+ if( myData[2*i]<=x && x<myData[2*(i+1)] )
{
x_ind_1 = i;
x_ind_2 = i+1;
}
x_ind_1 = n-1;
x_ind_2 = n-1;
- return false;
+ return ( fabs( x - myData[2*x_ind_2] ) < 1.e-10 );
}
FunctionExpr::FunctionExpr( const char* str, const int conv )
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_FaceSide.hxx
+// Created : Wed Jan 31 18:41:25 2007
+// Author : Edward AGAPOV (eap)
+// Module : SMESH
+
+#include "StdMeshers_FaceSide.hxx"
+
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+
+#include <Adaptor2d_Curve2d.hxx>
+#include <BRepAdaptor_CompCurve.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+
+#include <map>
+
+#include "utilities.h"
+
+//================================================================================
+/*!
+ * \brief Constructor of a side of one edge
+ * \param theFace - the face
+ * \param theEdge - the edge
+ */
+//================================================================================
+
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ const TopoDS_Edge& theEdge,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes)
+{
+ list<TopoDS_Edge> edges(1,theEdge);
+ *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward, theIgnoreMediumNodes );
+}
+
+//================================================================================
+/*!
+ * \brief Constructor of a side of several edges
+ * \param theFace - the face
+ * \param theEdge - the edge
+ */
+//================================================================================
+
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ list<TopoDS_Edge>& theEdges,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes)
+{
+ int nbEdges = theEdges.size();
+ myEdge.resize( nbEdges );
+ myC2d.resize( nbEdges );
+ myFirst.resize( nbEdges );
+ myLast.resize( nbEdges );
+ myNormPar.resize( nbEdges );
+ myLength = 0;
+ myNbPonits = myNbSegments = 0;
+ myMesh = theMesh;
+ myMissingVertexNodes = false;
+ myIgnoreMediumNodes = theIgnoreMediumNodes;
+ if ( nbEdges == 0 ) return;
+
+ SMESHDS_Mesh* meshDS = theMesh->GetMeshDS();
+ vector<double> len( nbEdges );
+
+ int nbDegen = 0;
+ list<TopoDS_Edge>::iterator edge = theEdges.begin();
+ for ( int index = 0; edge != theEdges.end(); ++index, ++edge )
+ {
+ int i = theIsForward ? index : nbEdges - index - 1;
+ len[i] = SMESH_Algo::EdgeLength( *edge );
+ if ( len[i] < DBL_MIN ) nbDegen++;
+ myLength += len[i];
+ myEdge[i] = *edge;
+ if ( !theIsForward ) myEdge[i].Reverse();
+
+ if ( theFace.IsNull() )
+ BRep_Tool::Range( *edge, myFirst[i], myLast[i] );
+ else
+ myC2d[i] = BRep_Tool::CurveOnSurface( *edge, theFace, myFirst[i], myLast[i] );
+ if ( myEdge[i].Orientation() == TopAbs_REVERSED )
+ std::swap( myFirst[i], myLast[i] );
+
+ if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( *edge )) {
+ int nbN = sm->NbNodes();
+ if ( theIgnoreMediumNodes ) {
+ SMDS_ElemIteratorPtr elemIt = sm->GetElements();
+ if ( elemIt->more() && elemIt->next()->IsQuadratic() )
+ nbN -= sm->NbElements();
+ }
+ myNbPonits += nbN;
+ myNbSegments += sm->NbElements();
+ }
+ if ( SMESH_Algo::VertexNode( TopExp::FirstVertex( *edge, 1), meshDS ))
+ myNbPonits += 1; // for the first end
+ else
+ myMissingVertexNodes = true;
+ }
+ if ( SMESH_Algo::VertexNode( TopExp::LastVertex( theEdges.back(), 1), meshDS ))
+ myNbPonits++; // for the last end
+ else
+ myMissingVertexNodes = true;
+
+ if ( nbEdges > 1 && myLength > DBL_MIN ) {
+ const double degenNormLen = 1.e-5;
+ double totLength = myLength;
+ if ( nbDegen )
+ totLength += myLength * degenNormLen * nbDegen;
+ double prevNormPar = 0;
+ for ( int i = 0; i < nbEdges; ++i ) {
+ if ( len[ i ] < DBL_MIN )
+ len[ i ] = myLength * degenNormLen;
+ myNormPar[ i ] = prevNormPar + len[i]/totLength;
+ prevNormPar = myNormPar[ i ];
+ }
+ }
+ myNormPar[nbEdges-1] = 1.;
+ //dump();
+}
+
+//================================================================================
+/*!
+ * \brief Return info on nodes on the side
+ * \retval UVPtStruct* - array of data structures
+ */
+//================================================================================
+
+const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
+ double constValue) const
+{
+ if ( myPoints.empty() ) {
+
+ if ( NbEdges() == 0 ) return myPoints;
+
+ SMESHDS_Mesh* meshDS = myMesh->GetMeshDS();
+
+ // sort nodes of all edges putting them into a map
+
+ map< double, const SMDS_MeshNode*> u2node;
+ //int nbOnDegen = 0;
+ for ( int i = 0; i < myEdge.size(); ++i )
+ {
+ // put 1st vertex node
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices( myEdge[i], VFirst, VLast, true);
+ const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VFirst, meshDS );
+ double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
+ if ( node ) { // internal nodes may be missing
+ u2node.insert( make_pair( prevNormPar, node ));
+ } else if ( i == 0 ) {
+ MESSAGE(" NO NODE on VERTEX" );
+ return myPoints;
+ }
+
+ // put 2nd vertex node for a last edge
+ if ( i+1 == myEdge.size() ) {
+ node = SMESH_Algo::VertexNode( VLast, meshDS );
+ if ( !node ) {
+ MESSAGE(" NO NODE on VERTEX" );
+ return myPoints;
+ }
+ u2node.insert( make_pair( 1., node ));
+ }
+
+ // put internal nodes
+ SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] );
+ if ( !sm ) continue;
+ SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+ double paramSize = myLast[i] - myFirst[i], r = myNormPar[i] - prevNormPar;
+ while ( nItr->more() ) {
+ const SMDS_MeshNode* node = nItr->next();
+ if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+ continue;
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double u = epos->GetUParameter();
+ // paramSize is signed so orientation is taken into account
+ double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
+#ifdef _DEBUG_
+ if ( normPar > 1 || normPar < 0) {
+ dump("DEBUG");
+ cout << "WRONG normPar: "<<normPar<< " prevNormPar="<<prevNormPar
+ << " u="<<u << " myFirst[i]="<<myFirst[i]<< " myLast[i]="<<myLast[i]
+ << " paramSize="<<paramSize<<endl;
+ }
+#endif
+ u2node.insert( make_pair( normPar, node ));
+ }
+ }
+ if ( u2node.size() != myNbPonits ) {
+ MESSAGE("Wrong node parameters on edges, u2node.size():"
+ <<u2node.size()<<" != myNbPonits:"<<myNbPonits);
+ return myPoints;
+ }
+
+ // fill array of UVPtStruct
+
+ vector<uvPtStruct>* points = const_cast<vector<uvPtStruct>*>( &myPoints );
+ points->resize( myNbPonits );
+
+ int EdgeIndex = 0;
+ double prevNormPar = 0, paramSize = myNormPar[ EdgeIndex ];
+ map< double, const SMDS_MeshNode*>::iterator u_node = u2node.begin();
+ for (int i = 0 ; u_node != u2node.end(); ++u_node, ++i ) {
+ UVPtStruct & uvPt = (*points)[i];
+ uvPt.node = u_node->second;
+ uvPt.x = uvPt.y = uvPt.normParam = u_node->first;
+ if ( isXConst ) uvPt.x = constValue;
+ else uvPt.y = constValue;
+ if ( myNormPar[ EdgeIndex ] < uvPt.normParam ) {
+ prevNormPar = myNormPar[ EdgeIndex ];
+ ++EdgeIndex;
+#ifdef _DEBUG_
+ if ( EdgeIndex >= myEdge.size() ) {
+ dump("DEBUG");
+ cout << "WRONg EdgeIndex " << 1+EdgeIndex
+ << " myNormPar.size()="<<myNormPar.size()
+ << " myNormPar["<< EdgeIndex<<"]="<< myNormPar[ EdgeIndex ]
+ << " uvPt.normParam="<<uvPt.normParam <<endl;
+ }
+#endif
+ paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
+ }
+ const SMDS_EdgePosition* epos =
+ dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition().get());
+ if ( epos ) {
+ uvPt.param = epos->GetUParameter();
+ }
+ else {
+ double r = ( uvPt.normParam - prevNormPar )/ paramSize;
+// uvPt.param = myFirst[EdgeIndex] * ( 1 - r ) + myLast[EdgeIndex] * r;
+ uvPt.param = ( r > 0.5 ? myLast[EdgeIndex] : myFirst[EdgeIndex] );
+ }
+ if ( !myC2d[ EdgeIndex ].IsNull() ) {
+ gp_Pnt2d p = myC2d[ EdgeIndex ]->Value( uvPt.param );
+ uvPt.u = p.X();
+ uvPt.v = p.Y();
+ }
+ else {
+ uvPt.u = uvPt.v = 1e+100;
+ }
+ }
+ }
+ return myPoints;
+}
+
+//================================================================================
+/*!
+ * \brief Falsificate info on nodes
+ * \param nbSeg - nb of segments on the side
+ * \retval UVPtStruct* - array of data structures
+ */
+//================================================================================
+
+const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int nbSeg,
+ bool isXConst,
+ double constValue) const
+{
+ if ( myFalsePoints.empty() ) {
+
+ if ( NbEdges() == 0 ) return myFalsePoints;
+
+ vector<uvPtStruct>* points = const_cast<vector<uvPtStruct>*>( &myFalsePoints );
+ points->resize( nbSeg+1 );
+
+ int EdgeIndex = 0;
+ double prevNormPar = 0, paramSize = myNormPar[ EdgeIndex ];
+ for (int i = 0 ; i < myFalsePoints.size(); ++i ) {
+ double normPar = double(i) / double(nbSeg);
+ UVPtStruct & uvPt = (*points)[i];
+ uvPt.node = 0;
+ uvPt.x = uvPt.y = uvPt.param = uvPt.normParam = normPar;
+ if ( isXConst ) uvPt.x = constValue;
+ else uvPt.y = constValue;
+ if ( myNormPar[ EdgeIndex ] < normPar ) {
+ prevNormPar = myNormPar[ EdgeIndex ];
+ ++EdgeIndex;
+ paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
+ }
+ double r = ( normPar - prevNormPar )/ paramSize;
+ uvPt.param = myFirst[EdgeIndex] * ( 1 - r ) + myLast[EdgeIndex] * r;
+ if ( !myC2d[ EdgeIndex ].IsNull() ) {
+ gp_Pnt2d p = myC2d[ EdgeIndex ]->Value( uvPt.param );
+ uvPt.u = p.X();
+ uvPt.v = p.Y();
+ }
+ else {
+ uvPt.u = uvPt.v = 1e+100;
+ }
+ }
+ }
+ return myFalsePoints;
+}
+// gp_Pnt StdMeshers_FaceSide::Value(double U) const
+// {
+// }
+
+//================================================================================
+/*!
+ * \brief reverse order of vector elements
+ * \param vec - vector to reverse
+ */
+//================================================================================
+
+template <typename T > void reverse(vector<T> & vec)
+{
+ for ( int f=0, r=vec.size()-1; f < r; ++f, --r )
+ std::swap( vec[f], vec[r] );
+}
+
+//================================================================================
+/*!
+ * \brief Change orientation of side geometry
+ */
+//================================================================================
+
+void StdMeshers_FaceSide::Reverse()
+{
+ int nbEdges = myEdge.size();
+ for ( int i = nbEdges-1; i >= 0; --i ) {
+ std::swap( myFirst[i], myLast[i] );
+ myEdge[i].Reverse();
+ if ( i > 0 ) // at the first loop 1. is overwritten
+ myNormPar[i] = 1 - myNormPar[i-1];
+ }
+ if ( nbEdges > 1 ) {
+ reverse( myEdge );
+ reverse( myC2d );
+ reverse( myFirst );
+ reverse( myLast );
+ reverse( myNormPar );
+ }
+ myNormPar[nbEdges-1]=1.;
+ myPoints.clear();
+ myFalsePoints.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Show side features
+ */
+//================================================================================
+
+void StdMeshers_FaceSide::dump(const char* msg) const
+{
+#ifdef _DEBUG_
+ cout << endl;
+ if (msg) cout << msg <<endl;
+ cout<<"NB EDGES: "<< myEdge.size() <<endl;
+ cout << "nbPoints: "<<myNbPonits<<" vecSize: " << myPoints.size()<<" "<<myFalsePoints.size() <<endl;
+ for ( int i=0; i<myEdge.size(); ++i)
+ {
+ cout << "\t"<<i+1<<endl;
+ cout << "\tEDGE: ";
+ if (myEdge[i].IsNull())
+ cout<<"NULL"<<endl;
+ else {
+ TopAbs::Print(myEdge[i].Orientation(),cout)<<" "<<myEdge[i].TShape().operator->()<<endl;
+ cout << "\tV1: " << TopExp::FirstVertex( myEdge[i], 1).TShape().operator->()
+ << " V2: " << TopExp::LastVertex( myEdge[i], 1).TShape().operator->() << endl;
+ }
+ cout << "\tC2d: ";
+ if (myC2d[i].IsNull()) cout<<"NULL"<<endl;
+ else cout << myC2d[i].operator->()<<endl;
+ cout << "\tF: "<<myFirst[i]<< " L: "<< myLast[i]<<endl;
+ cout << "\tnormPar: "<<myNormPar[i]<<endl;
+ }
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Creates a Adaptor2d_Curve2d to be used in SMESH_Block
+ * \retval Adaptor2d_Curve2d* -
+ */
+//================================================================================
+
+struct Adaptor2dCurve2d : public Adaptor2d_Curve2d
+{
+ const StdMeshers_FaceSide* mySide;
+ Adaptor2dCurve2d(const StdMeshers_FaceSide* faceSide):mySide(faceSide) {}
+ gp_Pnt2d Value(const Standard_Real U) const { return mySide->Value2d( U ); }
+ Standard_Real FirstParameter() const { return 0; }
+ Standard_Real LastParameter() const { return 1; }
+};
+
+Adaptor2d_Curve2d* StdMeshers_FaceSide::GetCurve2d() const
+{
+ return new Adaptor2dCurve2d( this );
+}
+
+//================================================================================
+/*!
+ * \brief Creates a fully functional Adaptor_Curve
+ */
+//================================================================================
+
+BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
+{
+ if ( myEdge.empty() )
+ return 0;
+
+// if ( myEdge.size() == 1 )
+// return new BRepAdaptor_Curve( myEdge[0] );
+
+ TopoDS_Wire aWire;
+ BRep_Builder aBuilder;
+ aBuilder.MakeWire(aWire);
+ for ( int i=0; i<myEdge.size(); ++i )
+ aBuilder.Add( aWire, myEdge[i] );
+ return new BRepAdaptor_CompCurve( aWire );
+}
+
+//================================================================================
+/*!
+ * \brief Return 2D point by normalized parameter
+ * \param U - normalized parameter value
+ * \retval gp_Pnt2d - point
+ */
+//================================================================================
+
+gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const
+{
+ if ( !myC2d[0].IsNull() ) {
+ int i = EdgeIndex( U );
+ double prevU = i ? myNormPar[ i-1 ] : 0;
+ double r = ( U - prevU )/ ( myNormPar[ i ] - prevU );
+ return myC2d[ i ]->Value( myFirst[i] * ( 1 - r ) + myLast[i] * r );
+ }
+ return gp_Pnt2d( 1e+100, 1e+100 );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_FaceSide.hxx
+// Created : Wed Jan 31 18:41:25 2007
+// Author : Edward AGAPOV (eap)
+// Module : SMESH
+
+#ifndef StdMeshers_FaceSide_HeaderFile
+#define StdMeshers_FaceSide_HeaderFile
+
+#include <gp_Pnt2d.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Geom2d_Curve.hxx>
+#include <TopExp.hxx>
+
+#include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+class SMDS_MeshNode;
+class SMESH_Mesh;
+class Adaptor2d_Curve2d;
+class Adaptor3d_Curve;
+class BRepAdaptor_CompCurve;
+class TopoDS_Face;
+
+typedef struct uvPtStruct
+{
+ double param;
+ //int curvIndex;
+ double normParam;
+ double u; // original 2d parameter
+ double v;
+ double x; // 2d parameter, normalized [0,1]
+ double y;
+ const SMDS_MeshNode * node;
+} UVPtStruct;
+
+class StdMeshers_FaceSide;
+typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr;
+typedef boost::shared_ptr< uvPtStruct > UVPtStructPtr;
+
+//================================================================================
+/*!
+ * \brief Represents a side of a quasi quadrilateral face.
+ * It can be composed of several edges. Gives access to geometry and 1D mesh of a side.
+ */
+//================================================================================
+
+class StdMeshers_FaceSide
+{
+public:
+ /*!
+ * \brief Wrap one edge
+ */
+ StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ const TopoDS_Edge& theEdge,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes);
+ /*!
+ * \brief Wrap several edges. Edges must be properly ordered and oriented.
+ */
+ StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ list<TopoDS_Edge>& theEdges,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes);
+ /*!
+ * \brief Change orientation of side geometry
+ */
+ void Reverse();
+ /*!
+ * \brief Return nb nodes on edges and vertices (+1 to be == GetUVPtStruct().size() )
+ */
+ int NbPoints() const { return myNbPonits; }
+ /*!
+ * \brief Return nb edges
+ */
+ int NbSegments() const { return myNbSegments; }
+ /*!
+ * \brief Return mesh
+ */
+ SMESH_Mesh* GetMesh() const { return myMesh; }
+ /*!
+ * \brief Return true if there vertices without nodes
+ */
+ bool MissVertexNode() const { return myMissingVertexNodes; }
+ /*!
+ * \brief Return detailed data on nodes
+ * \param isXConst - true if normalized parameter X is constant
+ * \param constValue - constant parameter value
+ *
+ * Missing nodes are allowed only on internal vertices
+ */
+ const vector<UVPtStruct>& GetUVPtStruct(bool isXConst, double constValue) const;
+ /*!
+ * \brief Simulates detailed data on nodes
+ * \param isXConst - true if normalized parameter X is constant
+ * \param constValue - constant parameter value
+ */
+ const vector<UVPtStruct>& SimulateUVPtStruct(int nbSeg,
+ bool isXConst,
+ double constValue) const;
+ /*!
+ * \brief Return edge and parameter on edge by normalized parameter
+ */
+ inline double Parameter(double U, TopoDS_Edge & edge) const;
+ /*!
+ * \brief Return UV by normalized parameter
+ */
+ gp_Pnt2d Value2d(double U) const;
+ /*!
+ * \brief Creates a Adaptor2d_Curve2d to be used in SMESH_Block
+ */
+ Adaptor2d_Curve2d* GetCurve2d() const;
+ /*!
+ * \brief Creates a fully functional Adaptor_Curve
+ */
+ BRepAdaptor_CompCurve* GetCurve3d() const;
+ /*!
+ * \brief Return nb of wrapped edges
+ */
+ int NbEdges() const { return myEdge.size(); }
+ /*!
+ * \brief Return i-th wrapped edge (count starts from zero)
+ */
+ const TopoDS_Edge& Edge(int i) const { return myEdge[i]; }
+ /*!
+ * \brief Return 1st vertex of the i-the edge (count starts from zero)
+ */
+ inline TopoDS_Vertex FirstVertex(int i=0) const;
+ /*!
+ * \brief Return last vertex of the i-the edge (count starts from zero)
+ */
+ inline TopoDS_Vertex LastVertex(int i=-1) const;
+ /*!
+ * \brief Return first normalized parameter of the i-the edge (count starts from zero)
+ */
+ inline double FirstParameter(int i) const;
+ /*!
+ * \brief Return ast normalized parameter of the i-the edge (count starts from zero)
+ */
+ inline double LastParameter(int i) const;
+ /*!
+ * \brief Return side length
+ */
+ double Length() const { return myLength; }
+ /*!
+ * \brief Return edge index corresponding to normalized parameter
+ */
+ inline int EdgeIndex( double U ) const;
+
+ //virtual gp_Pnt Value(double U) const;
+
+ void dump(const char* msg=0) const;
+
+
+protected:
+ vector<uvPtStruct> myPoints, myFalsePoints;
+ vector<TopoDS_Edge> myEdge;
+ vector<Handle(Geom2d_Curve)> myC2d;
+ vector<double> myFirst, myLast;
+ vector<double> myNormPar;
+ double myLength;
+ int myNbPonits, myNbSegments;
+ SMESH_Mesh* myMesh;
+ bool myMissingVertexNodes, myIgnoreMediumNodes;
+};
+
+
+//================================================================================
+/*!
+ * \brief Return edge index corresponding to normalized parameter
+ * \param U - the parameter
+ * \retval int - index
+ */
+//================================================================================
+
+inline int StdMeshers_FaceSide::EdgeIndex( double U ) const
+{
+ int i = myNormPar.size() - 1;
+ while ( i > 0 && U < myNormPar[ i-1 ] ) --i;
+ return i;
+}
+
+//================================================================================
+/*!
+ * \brief Return edge and parameter on edge by normalized parameter
+ * \param U - the parameter
+ * \retval double - pameter on a curve
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const
+{
+ int i = EdgeIndex( U );
+ edge = myEdge[ i ];
+ double prevU = i ? myNormPar[ i-1 ] : 0;
+ double r = ( U - prevU )/ ( myNormPar[ i ] - prevU );
+ return myFirst[i] * ( 1 - r ) + myLast[i] * r;
+}
+
+//================================================================================
+/*!
+ * \brief Return 1st vertex of the i-the edge
+ */
+//================================================================================
+
+inline TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const
+{
+ return i < myEdge.size() ? TopExp::FirstVertex( myEdge[i], 1 ) : TopoDS_Vertex();
+}
+
+//================================================================================
+/*!
+ * \brief Return last vertex of the i-the edge
+ */
+//================================================================================
+
+inline TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
+{
+ return i<0 ? TopExp::LastVertex( myEdge.back(), 1) : i<myEdge.size() ? TopExp::LastVertex( myEdge[i], 1 ) : TopoDS_Vertex();
+}
+
+//================================================================================
+/*!
+ * \brief Return first normalized parameter of the i-the edge
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::FirstParameter(int i) const
+{
+ return i==0 ? 0. : i<myNormPar.size() ? myNormPar[i-1] : 1.;
+}
+
+//================================================================================
+/*!
+ * \brief Return ast normalized parameter of the i-the edge
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::LastParameter(int i) const
+{
+ return i<myNormPar.size() ? myNormPar[i] : 1;
+}
+
+#endif
#include "StdMeshers_Hexa_3D.hxx"
#include "StdMeshers_Quadrangle_2D.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_Penta_3D.hxx"
+#include "StdMeshers_Prism_3D.hxx"
+
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Surface.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Handle_Geom2d_Curve.hxx>
-#include <Handle_Geom_Curve.hxx>
#include <gp_Pnt2d.hxx>
#include "utilities.h"
#include "Utils_ExceptHandlers.hxx"
-//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f
-#include "StdMeshers_Penta_3D.hxx"
+typedef SMESH_Comment TComm;
using namespace std;
-static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
-//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
//=============================================================================
/*!
*/
//=============================================================================
-StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
- SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen)
+ :SMESH_3D_Algo(hypId, studyId, gen)
{
MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
_name = "Hexa_3D";
bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res)
{
for (int i = 0; i < 6; i++) {
- StdMeshers_Quadrangle_2D::QuadDelete(theQuads[i]);
+ delete theQuads[i];
theQuads[i] = NULL;
}
return res;
//=============================================================================
bool StdMeshers_Hexa_3D::CheckHypothesis
- (SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape,
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus)
{
- //MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis");
-
- bool isOk = true;
- aStatus = SMESH_Hypothesis::HYP_OK;
-
- // nothing to check
-
- return isOk;
+ // check nb of faces in the shape
+ aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY;
+ int nbFaces = 0;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
+ if ( ++nbFaces > 6 )
+ return false;
+
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ return true;
}
//=======================================================================
gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
double minDist = DBL_MAX;
- int nbhoriz = Min(quad->nbPts[0], quad->nbPts[2]);
- int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
+ int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
+ int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
for (int i = 1; i < nbhoriz - 1; i++) {
for (int j = 1; j < nbvertic - 1; j++) {
int ij = j * nbhoriz + i;
*/
//=============================================================================
-bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape)throw(SALOME_Exception)
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape) throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
MESSAGE("StdMeshers_Hexa_3D::Compute");
// 0. - shape and face mesh verification
// 0.1 - shape must be a solid (or a shell) with 6 faces
- //MESSAGE("---");
vector < SMESH_subMesh * >meshFaces;
for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
ASSERT(aSubMesh);
meshFaces.push_back(aSubMesh);
}
- if (meshFaces.size() != 6) {
- SCRUTE(meshFaces.size());
- return false;
- }
+ if (meshFaces.size() != 6)
+ return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in block");
// 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
- //MESSAGE("---");
// tool for working with quadratic elements
SMESH_MesherHelper aTool (aMesh);
for (int i = 0; i < 6; i++)
aQuads[i] = 0;
- for (int i = 0; i < 6; i++) {
+ for (int i = 0; i < 6; i++)
+ {
TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
string algoName = algo->GetName();
}
}
if ( ! isAllQuad ) {
- //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
- bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
- return ClearAndReturn( aQuads, bIsOk );
+ SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+ return ClearAndReturn( aQuads, error(err));
}
StdMeshers_Quadrangle_2D *quadAlgo =
dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh);
}
catch(SALOME_Exception & S_ex) {
- return ClearAndReturn( aQuads, false );
+ return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) <<
+ " Raised by StdMeshers_Quadrangle_2D "
+ " on face #" << meshDS->ShapeToIndex( aFace )));
}
// 0.2.1 - number of points on the opposite edges must be the same
- if (aQuads[i]->nbPts[0] != aQuads[i]->nbPts[2] ||
- aQuads[i]->nbPts[1] != aQuads[i]->nbPts[3]) {
+ if (aQuads[i]->side[0]->NbPoints() != aQuads[i]->side[2]->NbPoints() ||
+ aQuads[i]->side[1]->NbPoints() != aQuads[i]->side[3]->NbPoints()
+ /*aQuads[i]->side[0]->NbEdges() != 1 ||
+ aQuads[i]->side[1]->NbEdges() != 1 ||
+ aQuads[i]->side[2]->NbEdges() != 1 ||
+ aQuads[i]->side[3]->NbEdges() != 1*/) {
MESSAGE("different number of points on the opposite edges of face " << i);
- // ASSERT(0);
- // \begin{E.A.}
// Try to go into penta algorithm 'cause it has been improved.
- // return ClearAndReturn( aQuads, false );
- bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
- return ClearAndReturn( aQuads, bIsOk );
- // \end{E.A.}
+ SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+ return ClearAndReturn( aQuads, error(err));
}
}
// 1. - identify faces and vertices of the "cube"
// 1.1 - ancestor maps vertex->edges in the cube
- //MESSAGE("---");
TopTools_IndexedDataMapOfShapeListOfShape MS;
TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
// 1.2 - first face is choosen as face Y=0 of the unit cube
- //MESSAGE("---");
const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
const TopoDS_Face & F = TopoDS::Face(aFace);
// 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
- //MESSAGE("---");
-
- int i = 0;
- TopoDS_Edge E = aQuads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopoDS_Vertex VFirst, VLast;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
- bool isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
-
- if (isForward) {
- aCube.V000 = VFirst; // will be (0,0,0) on the unit cube
- aCube.V100 = VLast; // will be (1,0,0) on the unit cube
- }
- else {
- aCube.V000 = VLast;
- aCube.V100 = VFirst;
- }
- i = 1;
- E = aQuads[0]->edge[i];
- C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopExp::Vertices(E, VFirst, VLast);
- isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
- if (isForward)
- aCube.V101 = VLast; // will be (1,0,1) on the unit cube
- else
- aCube.V101 = VFirst;
-
- i = 2;
- E = aQuads[0]->edge[i];
- C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopExp::Vertices(E, VFirst, VLast);
- isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
- if (isForward)
- aCube.V001 = VLast; // will be (0,0,1) on the unit cube
- else
- aCube.V001 = VFirst;
-
- // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
- // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
- // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0)
- // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
- //MESSAGE("---");
-
- TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V000, MS);
- ASSERT(!E_0Y0.IsNull());
-
- TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V100, MS);
- ASSERT(!E_1Y0.IsNull());
-
- TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V101, MS);
- ASSERT(!E_1Y1.IsNull());
-
- TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V001, MS);
- ASSERT(!E_0Y1.IsNull());
-
- // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
- //MESSAGE("---");
-
- TopExp::Vertices(E_0Y0, VFirst, VLast);
- if (VFirst.IsSame(aCube.V000))
- aCube.V010 = VLast;
- else
- aCube.V010 = VFirst;
-
- TopExp::Vertices(E_1Y0, VFirst, VLast);
- if (VFirst.IsSame(aCube.V100))
- aCube.V110 = VLast;
- else
- aCube.V110 = VFirst;
-
- TopExp::Vertices(E_1Y1, VFirst, VLast);
- if (VFirst.IsSame(aCube.V101))
- aCube.V111 = VLast;
- else
- aCube.V111 = VFirst;
-
- TopExp::Vertices(E_0Y1, VFirst, VLast);
- if (VFirst.IsSame(aCube.V001))
- aCube.V011 = VLast;
- else
- aCube.V011 = VFirst;
+ aCube.V000 = aQuads[0]->side[0]->FirstVertex(); // will be (0,0,0) on the unit cube
+ aCube.V100 = aQuads[0]->side[0]->LastVertex(); // will be (1,0,0) on the unit cube
+ aCube.V001 = aQuads[0]->side[2]->FirstVertex(); // will be (0,0,1) on the unit cube
+ aCube.V101 = aQuads[0]->side[2]->LastVertex(); // will be (1,0,1) on the unit cube
+
+ TopTools_IndexedMapOfShape MV0;
+ TopExp::MapShapes(F, TopAbs_VERTEX, MV0);
+
+ aCube.V010 = OppositeVertex( aCube.V000, MV0, aQuads);
+ aCube.V110 = OppositeVertex( aCube.V100, MV0, aQuads);
+ aCube.V011 = OppositeVertex( aCube.V001, MV0, aQuads);
+ aCube.V111 = OppositeVertex( aCube.V101, MV0, aQuads);
// 1.6 - find remaining faces given 4 vertices
- //MESSAGE("---");
int _indY0 = 0;
aCube.quad_Y0 = aQuads[_indY0];
aCube.V100, aCube.V101, aCube.V110, aCube.V111);
aCube.quad_X1 = aQuads[_indX1];
- //MESSAGE("---");
-
// 1.7 - get convertion coefs from face 2D normalized to 3D normalized
Conv2DStruct cx0; // for face X=0
// 1.8 - create a 3D structure for normalized values
- //MESSAGE("---");
- int nbx = aCube.quad_Z0->nbPts[0];
- if (cz0.a1 == 0.) nbx = aCube.quad_Z0->nbPts[1];
+ int nbx = aCube.quad_Z0->side[0]->NbPoints();
+ if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints();
- int nby = aCube.quad_X0->nbPts[0];
- if (cx0.a1 == 0.) nby = aCube.quad_X0->nbPts[1];
+ int nby = aCube.quad_X0->side[0]->NbPoints();
+ if (cx0.a1 == 0.) nby = aCube.quad_X0->side[1]->NbPoints();
- int nbz = aCube.quad_Y0->nbPts[0];
- if (cy0.a1 != 0.) nbz = aCube.quad_Y0->nbPts[1];
+ int nbz = aCube.quad_Y0->side[0]->NbPoints();
+ if (cy0.a1 != 0.) nbz = aCube.quad_Y0->side[1]->NbPoints();
int i1, j1, nbxyz = nbx * nby * nbz;
Point3DStruct *np = new Point3DStruct[nbxyz];
faceQuadStruct *quad = aCube.quad_X0;
int i = 0; // j = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
faceQuadStruct *quad = aCube.quad_X1;
int i = nbx - 1; // j = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
while(itf->more()) {
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
faceQuadStruct *quad = aCube.quad_Y0;
int j = 0; // i = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
while(itf->more()) {
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
faceQuadStruct *quad = aCube.quad_Y1;
int j = nby - 1; // i = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
while(itf->more()) {
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
faceQuadStruct *quad = aCube.quad_Z0;
int k = 0; // i = x/face , j = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
while(itf->more()) {
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
faceQuadStruct *quad = aCube.quad_Z1;
int k = nbz - 1; // i = x/face , j = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbright = quad->side[1]->NbPoints();
while(itf->more()) {
const SMDS_MeshNode * node = itf->next();
if(aTool.IsMedium(node))
continue;
- findIJ( node, quad, i1, j1 );
+ if ( !findIJ( node, quad, i1, j1 ))
+ return ClearAndReturn( aQuads, false );
int ij1 = j1 * nbdown + i1;
quad->uv_grid[ij1].node = node;
}
SMDS_MeshVolume * elt;
if ( isForw ) {
- //elt = meshDS->AddVolume(np[n1].node, np[n2].node,
- // np[n3].node, np[n4].node,
- // np[n5].node, np[n6].node,
- // np[n7].node, np[n8].node);
elt = aTool.AddVolume(np[n1].node, np[n2].node,
np[n3].node, np[n4].node,
np[n5].node, np[n6].node,
np[n7].node, np[n8].node);
}
else {
- //elt = meshDS->AddVolume(np[n1].node, np[n4].node,
- // np[n3].node, np[n2].node,
- // np[n5].node, np[n8].node,
- // np[n7].node, np[n6].node);
elt = aTool.AddVolume(np[n1].node, np[n4].node,
np[n3].node, np[n2].node,
np[n5].node, np[n8].node,
}
}
if ( np ) delete [] np;
- //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
return ClearAndReturn( aQuads, true );
}
*/
//=============================================================================
-void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby,
- int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS)
+void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, int nbz,
+ Point3DStruct * np, const SMESHDS_Mesh * meshDS)
{
int ijk = k * nbx * nby + j * nbx + i;
const SMDS_MeshNode * node = np[ijk].node;
const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv)
{
// MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs");
- const TopoDS_Face & F = TopoDS::Face(aShape);
- TopoDS_Edge E = quad.edge[0];
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopoDS_Vertex VFirst, VLast;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
- bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
- TopoDS_Vertex VA, VB;
- if (isForward)
- {
- VA = VFirst;
- VB = VLast;
- }
- else
- {
- VA = VLast;
- VB = VFirst;
- }
+// const TopoDS_Face & F = TopoDS::Face(aShape);
+// TopoDS_Edge E = quad.edge[0];
+// double f, l;
+// Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+// TopoDS_Vertex VFirst, VLast;
+// TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+// bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
+ TopoDS_Vertex VA, VB;
+// if (isForward)
+// {
+// VA = VFirst;
+// VB = VLast;
+// }
+// else
+// {
+// VA = VLast;
+// VB = VFirst;
+// }
+ VA = quad.side[0]->FirstVertex();
+ VB = quad.side[0]->LastVertex();
+
int a1, b1, c1, a2, b2, c2;
if (VA.IsSame(V0))
if (VB.IsSame(V1))
conv.b2 = b2;
conv.c2 = c2;
- int nbdown = quad.nbPts[0];
- int nbright = quad.nbPts[1];
+ int nbdown = quad.side[0]->NbPoints();
+ int nbright = quad.side[1]->NbPoints();
conv.ia = int (a1);
conv.ib = int (b1);
conv.ic =
// MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc);
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save)
-{
- return save;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & StdMeshers_Hexa_3D::LoadFrom(istream & load)
-{
- return load;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp)
-{
- return hyp.SaveTo( save );
-}
-
-//=============================================================================
+//================================================================================
/*!
- *
+ * \brief Find a vertex opposite to the given vertex of aQuads[0]
+ * \param aVertex - the vertex
+ * \param aFace - the face aVertex belongs to
+ * \param aQuads - quads
+ * \retval TopoDS_Vertex - found vertex
*/
-//=============================================================================
+//================================================================================
-istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
+TopoDS_Vertex StdMeshers_Hexa_3D::OppositeVertex(const TopoDS_Vertex& aVertex,
+ const TopTools_IndexedMapOfShape& aQuads0Vertices,
+ FaceQuadStruct* aQuads[6])
{
- return hyp.LoadFrom( load );
+ int i, j;
+ for ( i = 1; i < 6; ++i )
+ {
+ TopoDS_Vertex VV[] = { aQuads[i]->side[0]->FirstVertex(),
+ aQuads[i]->side[0]->LastVertex() ,
+ aQuads[i]->side[2]->LastVertex() ,
+ aQuads[i]->side[2]->FirstVertex() };
+ for ( j = 0; j < 4; ++j )
+ if ( aVertex.IsSame( VV[ j ]))
+ break;
+ if ( j < 4 ) {
+ int jPrev = j ? j - 1 : 3;
+ int jNext = (j + 1) % 4;
+ if ( aQuads0Vertices.Contains( VV[ jPrev ] ))
+ return VV[ jNext ];
+ else
+ return VV[ jPrev ];
+ }
+ }
+ return TopoDS_Vertex();
}
//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f
//function : ComputePentahedralMesh
//purpose :
//=======================================================================
-bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+
+SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)
{
//printf(" ComputePentahedralMesh HERE\n");
//
bool bOK;
+ SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
//int iErr;
StdMeshers_Penta_3D anAlgo;
//
bOK=anAlgo.Compute(aMesh, aShape);
- /*
- iErr=anAlgo.ErrorStatus();
-
- if (iErr) {
- printf(" *** Error# %d\n", iErr);
- }
- else {
- printf(" *** No errors# %d\n", iErr);
+ //
+ err = anAlgo.GetComputeError();
+ //
+ if ( !bOK && anAlgo.ErrorStatus() == 5 )
+ {
+ static StdMeshers_Prism_3D * aPrism3D = 0;
+ if ( !aPrism3D ) {
+ SMESH_Gen* gen = aMesh.GetGen();
+ aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+ }
+ SMESH_Hypothesis::Hypothesis_Status aStatus;
+ if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+ bOK = aPrism3D->Compute( aMesh, aShape );
+ err = aPrism3D->GetComputeError();
+ }
}
- */
- return bOK;
+ return err;
}
#include "SMESH_MesherHelper.hxx"
+class TopTools_IndexedMapOfShape;
+
typedef struct point3Dstruct
{
const SMDS_MeshNode * node;
const TopoDS_Shape& aShape)
throw (SALOME_Exception);
- ostream & SaveTo(ostream & save);
- istream & LoadFrom(istream & load);
- friend ostream & operator << (ostream & save, StdMeshers_Hexa_3D & hyp);
- friend istream & operator >> (istream & load, StdMeshers_Hexa_3D & hyp);
+ static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex,
+ const TopTools_IndexedMapOfShape& aQuads0Vertices,
+ FaceQuadStruct* aQuads[6]);
protected:
TopoDS_Edge
// $Header$
#include "StdMeshers_MEFISTO_2D.hxx"
+
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
+#include "StdMeshers_FaceSide.hxx"
#include "StdMeshers_MaxElementArea.hxx"
#include "StdMeshers_LengthFromEdges.hxx"
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
#include <Geom_Surface.hxx>
-#include <GeomAdaptor_Curve.hxx>
#include <Geom2d_Curve.hxx>
#include <gp_Pnt2d.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-#include <GCPnts_UniformAbscissa.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+
+using namespace std;
//=============================================================================
/*!
*/
//=============================================================================
-StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
- SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen * gen):
+ SMESH_2D_Algo(hypId, studyId, gen)
{
MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
_name = "MEFISTO_2D";
//=============================================================================
bool StdMeshers_MEFISTO_2D::CheckHypothesis
- (SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape,
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus)
{
- //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
+ _hypMaxElementArea = NULL;
+ _hypLengthFromEdges = NULL;
- _hypMaxElementArea = NULL;
- _hypLengthFromEdges = NULL;
+ list <const SMESHDS_Hypothesis * >::const_iterator itl;
+ const SMESHDS_Hypothesis *theHyp;
- list <const SMESHDS_Hypothesis * >::const_iterator itl;
- const SMESHDS_Hypothesis *theHyp;
+ const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+ int nbHyp = hyps.size();
+ if (!nbHyp)
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
- const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
- int nbHyp = hyps.size();
- if (!nbHyp)
- {
- aStatus = SMESH_Hypothesis::HYP_MISSING;
- return false; // can't work with no hypothesis
- }
+ itl = hyps.begin();
+ theHyp = (*itl); // use only the first hypothesis
- itl = hyps.begin();
- theHyp = (*itl); // use only the first hypothesis
-
- string hypName = theHyp->GetName();
- //int hypId = theHyp->GetID();
- //SCRUTE(hypName);
-
- bool isOk = false;
-
- if (hypName == "MaxElementArea")
- {
- _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
- ASSERT(_hypMaxElementArea);
- _maxElementArea = _hypMaxElementArea->GetMaxArea();
- _edgeLength = 0;
- isOk = true;
- aStatus = SMESH_Hypothesis::HYP_OK;
- }
-
- else if (hypName == "LengthFromEdges")
- {
- _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
- ASSERT(_hypLengthFromEdges);
- _edgeLength = 0;
- _maxElementArea = 0;
- isOk = true;
- aStatus = SMESH_Hypothesis::HYP_OK;
- }
- else
- aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
-
- if (isOk)
- {
- isOk = false;
- if (_maxElementArea > 0)
- {
-// _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
- _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
- isOk = true;
- }
- else
- isOk = (_hypLengthFromEdges != NULL); // **** check mode
- if (!isOk)
- aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
- }
-
- //SCRUTE(_edgeLength);
- //SCRUTE(_maxElementArea);
- return isOk;
+ string hypName = theHyp->GetName();
+
+ bool isOk = false;
+
+ if (hypName == "MaxElementArea")
+ {
+ _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
+ ASSERT(_hypMaxElementArea);
+ _maxElementArea = _hypMaxElementArea->GetMaxArea();
+ _edgeLength = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+
+ else if (hypName == "LengthFromEdges")
+ {
+ _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
+ ASSERT(_hypLengthFromEdges);
+ _edgeLength = 0;
+ _maxElementArea = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+ else
+ aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+ if (isOk)
+ {
+ isOk = false;
+ if (_maxElementArea > 0)
+ {
+ //_edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
+ _edgeLength = sqrt(2. * _maxElementArea/sqrt(3.0));
+ isOk = true;
+ }
+ else
+ isOk = (_hypLengthFromEdges != NULL); // **** check mode
+ if (!isOk)
+ aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+ }
+
+ return isOk;
}
//=============================================================================
{
MESSAGE("StdMeshers_MEFISTO_2D::Compute");
- if (_hypLengthFromEdges)
- _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
-
- bool isOk = false;
- //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+ TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
+
+ // helper builds quadratic mesh if necessary
+ SMESH_MesherHelper helper(aMesh);
+ myTool = &helper;
+ _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+ const bool ignoreMediumNodes = _quadraticMesh;
+
+ // get all edges of a face
+ TopoDS_Vertex V1;
+ list< TopoDS_Edge > edges;
+ list< int > nbEdgesInWires;
+ int nbWires = SMESH_Block::GetOrderedEdges (F, V1, edges, nbEdgesInWires);
+
+ if (_hypLengthFromEdges) _edgeLength = 0;
+
+ // split list of all edges into separate wires
+ TWireVector wires ( nbWires );
+ list< int >::iterator nbE = nbEdgesInWires.begin();
+ list< TopoDS_Edge >::iterator from, to;
+ from = to = edges.begin();
+ for ( int iW = 0; iW < nbWires; ++iW )
+ {
+ std::advance( to, *nbE++ );
+ list< TopoDS_Edge > wireEdges( from, to );
+ // assure that there is a node on the first vertex
+ // as StdMeshers_FaceSide::GetUVPtStruct() requires
+ while ( !VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
+ aMesh.GetMeshDS()))
+ {
+ wireEdges.splice(wireEdges.end(), wireEdges,
+ wireEdges.begin(), ++wireEdges.begin());
+ if ( from->IsSame( wireEdges.front() ))
+ return error(COMPERR_BAD_INPUT_MESH,"No nodes on vertices");
+ }
+ StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh,
+ true, ignoreMediumNodes);
+ wires[ iW ] = StdMeshers_FaceSidePtr( wire );
+ if (_hypLengthFromEdges && wire->NbSegments() )
+ _edgeLength += wire->Length() / wire->NbSegments();
+ from = to;
+ }
+ if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
+ return error(COMPERR_BAD_INPUT_MESH,
+ SMESH_Comment("Too few segments")<<wires[0]->NbSegments());
- const TopoDS_Face & FF = TopoDS::Face(aShape);
- bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
- TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+ if (_hypLengthFromEdges && _edgeLength < DBL_MIN )
+ _edgeLength = 100;
- Z nblf; //nombre de lignes fermees (enveloppe en tete)
- Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
- R2 *uvslf = NULL;
- Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
+ Z nblf; //nombre de lignes fermees (enveloppe en tete)
+ Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
+ R2 *uvslf = NULL;
+ Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
R2 *uvpti = NULL;
Z nbst;
Z *nust = NULL;
Z ierr = 0;
- Z nutysu = 1; // 1: il existe un fonction areteideale_()
- // Z nutysu=0; // 0: on utilise aretmx
- R aretmx = _edgeLength; // longueur max aretes future triangulation
+ Z nutysu = 1; // 1: il existe un fonction areteideale_()
+ // Z nutysu=0; // 0: on utilise aretmx
+ R aretmx = _edgeLength; // longueur max aretes future triangulation
- nblf = NumberOfWires(F);
+ nblf = nbWires;
nudslf = new Z[1 + nblf];
nudslf[0] = 0;
int iw = 1;
int nbpnt = 0;
- myTool = new SMESH_MesherHelper(aMesh);
- _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
-
- if ( _quadraticMesh && _hypLengthFromEdges )
- aretmx *= 2.;
-
- myOuterWire = BRepTools::OuterWire(F);
- nbpnt += NumberOfPoints(aMesh, myOuterWire);
- if ( nbpnt < 3 ) { // ex: a circle with 2 segments
- delete myTool; myTool = 0;
- return false;
- }
- nudslf[iw++] = nbpnt;
-
- for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
- const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
- if (!myOuterWire.IsSame(W)) {
- nbpnt += NumberOfPoints(aMesh, W);
- nudslf[iw++] = nbpnt;
- }
+ // count nb of input points
+ for ( int iW = 0; iW < nbWires; ++iW )
+ {
+ nbpnt += wires[iW]->NbPoints() - 1;
+ nudslf[iw++] = nbpnt;
}
- // avoid passing same uv points for a vertex common to 2 wires
- TopTools_IndexedDataMapOfShapeListOfShape VWMap;
- if ( iw - 1 > 1 ) // nbofWires > 1
- TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
-
uvslf = new R2[nudslf[nblf]];
- int m = 0;
double scalex, scaley;
ComputeScaleOnFace(aMesh, F, scalex, scaley);
- map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
- if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
- mefistoToDS, scalex, scaley, VWMap) ) {
- delete myTool; myTool = 0;
- return false;
- }
+ // correspondence mefisto index --> Nodes
+ vector< const SMDS_MeshNode*> mefistoToDS(nbpnt, (const SMDS_MeshNode*)0);
- for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+ bool isOk = false;
+
+ // fill input points UV
+ if ( LoadPoints(wires, uvslf, mefistoToDS, scalex, scaley) )
{
- const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
- if (!myOuterWire.IsSame(W))
+ // Compute
+ aptrte(nutysu, aretmx,
+ nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+ if (ierr == 0)
{
- if (! LoadPoints(aMesh, F, W, uvslf, m,
- mefistoToDS, scalex, scaley, VWMap )) {
- delete myTool; myTool = 0;
- return false;
- }
+ MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+ MESSAGE(" Node Number " << nbst);
+ StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
+ isOk = true;
+ }
+ else
+ {
+ error(ierr,"Error in Triangulation (aptrte())");
}
}
-
- uvst = NULL;
- nust = NULL;
- aptrte(nutysu, aretmx,
- nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
-
- if (ierr == 0)
- {
- MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
- MESSAGE(" Node Number " << nbst);
- StoreResult(aMesh, nbst, uvst, nbt, nust, F,
- faceIsForward, mefistoToDS, scalex, scaley);
- isOk = true;
- }
- else
- {
- MESSAGE("Error in Triangulation");
- isOk = false;
- }
- if (nudslf != NULL)
- delete[]nudslf;
- if (uvslf != NULL)
- delete[]uvslf;
- if (uvst != NULL)
- delete[]uvst;
- if (nust != NULL)
- delete[]nust;
- delete myTool; myTool = 0;
+ if (nudslf != NULL) delete[]nudslf;
+ if (uvslf != NULL) delete[]uvslf;
+ if (uvst != NULL) delete[]uvst;
+ if (nust != NULL) delete[]nust;
return isOk;
}
//purpose :
//=======================================================================
-static bool fixCommonVertexUV (gp_Pnt2d & theUV,
+static bool fixCommonVertexUV (R2 & theUV,
const TopoDS_Vertex& theV,
- const TopoDS_Wire& theW,
- const TopoDS_Wire& theOW,
const TopoDS_Face& theF,
const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
SMESH_Mesh & theMesh,
- bool CreateQuadratic)
+ const double theScaleX,
+ const double theScaleY,
+ const bool theCreateQuadratic)
{
- if( theW.IsSame( theOW ) ||
- !theVWMap.Contains( theV )) return false;
+ if( !theVWMap.Contains( theV )) return false;
// check if there is another wire sharing theV
const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
TopTools_ListIteratorOfListOfShape aWIt;
+ TopTools_MapOfShape aWires;
for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
- if ( !theW.IsSame( aWIt.Value() ))
- break;
- if ( !aWIt.More() ) return false;
+ aWires.Add( aWIt.Value() );
+ if ( aWires.Extent() < 2 ) return false;
+
+ TopoDS_Shape anOuterWire = BRepTools::OuterWire(theF);
+ TopoDS_Shape anInnerWire;
+ for ( aWIt.Initialize( WList ); aWIt.More() && anInnerWire.IsNull(); aWIt.Next() )
+ if ( !anOuterWire.IsSame( aWIt.Value() ))
+ anInnerWire = aWIt.Value();
TopTools_ListOfShape EList;
list< double > UList;
// find edges of theW sharing theV
// and find 2d normal to them at theV
gp_Vec2d N(0.,0.);
- TopoDS_Iterator itE( theW );
+ TopoDS_Iterator itE( anInnerWire );
for ( ; itE.More(); itE.Next() )
{
const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
gp_Vec2d d1;
gp_Pnt2d p;
C2d->D1( u, p, d1 );
- gp_Vec2d n( d1.Y(), -d1.X() );
+ gp_Vec2d n( d1.Y() * theScaleX, -d1.X() * theScaleY);
if ( E.Orientation() == TopAbs_REVERSED )
n.Reverse();
N += n.Normalized();
// define step size by which to move theUV
gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
+ gp_Pnt2d thisUV( theUV.x, theUV.y );
double maxDist = -DBL_MAX;
TopTools_ListIteratorOfListOfShape aEIt (EList);
list< double >::iterator aUIt = UList.begin();
while ( nIt->more() ) {
const SMDS_MeshNode* node = nIt->next();
// check if node is medium
- if ( CreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
+ if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
continue;
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
}
bool isFirstCommon = ( *aUIt == f );
gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
- double dist = theUV.SquareDistance( uv );
+ double dist = thisUV.SquareDistance( uv );
if ( dist > maxDist ) {
maxDist = dist;
nextUV = uv;
}
}
R2 uv0, uv1, uv2;
- uv0.x = theUV.X(); uv0.y = theUV.Y();
+ uv0.x = thisUV.X(); uv0.y = thisUV.Y();
uv1.x = nextUV.X(); uv1.y = nextUV.Y();
- uv2.x = uv0.x; uv2.y = uv0.y;
+ uv2.x = thisUV.X(); uv2.y = thisUV.Y();
+
+ uv1.x *= theScaleX; uv1.y *= theScaleY;
+
if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
{
- double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
+ double step = thisUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
// move theUV along the normal by the step
N *= step;
- MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
+ MESSAGE("--fixCommonVertexUV move(" << theUV.x << " " << theUV.x
<< ") by (" << N.X() << " " << N.Y() << ")"
<< endl << "--- MAX DIST " << maxDist);
- theUV.SetXY( theUV.XY() + N.XY() );
+ theUV.x += N.X();
+ theUV.y += N.Y();
return true;
}
*/
//=============================================================================
-bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
- const TopoDS_Face & FF,
- const TopoDS_Wire & WW,
- R2 * uvslf,
- int & m,
- map<int, const SMDS_MeshNode*>&mefistoToDS,
- double scalex,
- double scaley,
- const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
+bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires,
+ R2 * uvslf,
+ vector<const SMDS_MeshNode*>& mefistoToDS,
+ double scalex,
+ double scaley)
{
- // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
+ // to avoid passing same uv points for a vertex common to 2 wires
+ TopoDS_Face F;
+ TopTools_IndexedDataMapOfShapeListOfShape VWMap;
+ if ( wires.size() > 1 )
+ {
+ F = TopoDS::Face( myTool->GetSubShape() );
+ TopExp::MapShapesAndAncestors( F, TopAbs_VERTEX, TopAbs_WIRE, VWMap );
+ int nbVertices = 0;
+ for ( int iW = 0; iW < wires.size(); ++iW )
+ nbVertices += wires[ iW ]->NbEdges();
+ if ( nbVertices == VWMap.Extent() )
+ VWMap.Clear(); // wires have no common vertices
+ }
- TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+ const bool isXConst = false; // meaningles here
+ const double constValue = 0; // meaningles here
+ int m = 0;
list< int > mOnVertex;
- gp_XY scale( scalex, scaley );
-
- TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
- BRepTools_WireExplorer wexp(W, F);
- for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
+ for ( int iW = 0; iW < wires.size(); ++iW )
{
- const TopoDS_Edge & E = wexp.Current();
- bool isForward = (E.Orientation() == TopAbs_FORWARD);
-
- // --- IDNodes of first and last Vertex
-
- TopoDS_Vertex VFirst, VLast, V;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
- V = isForward ? VFirst : VLast;
-
- ASSERT(!V.IsNull());
- SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
- if ( !lid->more() ) {
- MESSAGE (" NO NODE BUILT ON VERTEX ");
- return false;
+ const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
+ if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
+ return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
+ << iW << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
+ }
+ if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
+ MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
+ return error(dfltErr(),"Internal error");
}
- const SMDS_MeshNode* idFirst = lid->next();
-
- // --- edge internal IDNodes (relies on good order storage, not checked)
-
- map<double, const SMDS_MeshNode*> params;
- const SMDS_MeshNode * node;
- SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
- while ( nodeIt->more() )
+ vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
+ for ( ++uvPt; uvPt != uvPtVec.end(); ++uvPt )
{
- node = nodeIt->next();
- if ( _quadraticMesh && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
- continue;
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- if ( !isForward ) param = -param;
- if ( !params.insert( make_pair( param, node )).second )
- {
- MESSAGE( "BAD NODE ON EDGE POSITIONS" );
- return false;
- }
+ // bind mefisto ID to node
+ mefistoToDS[m] = uvPt->node;
+ // set UV
+ uvslf[m].x = uvPt->u * scalex;
+ uvslf[m].y = uvPt->v * scaley;
+ if ( uvPt->node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+ mOnVertex.push_back( m );
+ m++;
}
- // --- load 2D values into MEFISTO structure,
- // add IDNodes in mefistoToDS map
-
- double f, l, uFirst, u;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- uFirst = isForward ? f : l;
-
- // vertex node
- gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
- if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
- myNodesOnCommonV.push_back( idFirst );
- mOnVertex.push_back( m );
- uvslf[m].x = p.X();
- uvslf[m].y = p.Y();
- mefistoToDS[m + 1] = idFirst;
- //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
- //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
- m++;
-
- // internal nodes
- map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
- for ( int i = 0; u_n != params.end(); ++u_n, ++i )
+ int mFirst = mOnVertex.front(), mLast = m - 1;
+ list< int >::iterator mIt = mOnVertex.begin();
+ for ( ; mIt != mOnVertex.end(); ++mIt)
{
- u = isForward ? u_n->first : - u_n->first;
- gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
- uvslf[m].x = p.X();
- uvslf[m].y = p.Y();
- mefistoToDS[m + 1] = u_n->second;
- //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
- //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
- m++;
+ int m = *mIt;
+ if ( iW && !VWMap.IsEmpty()) { // except outer wire
+ // avoid passing same uv point for a vertex common to 2 wires
+ int vID = mefistoToDS[m]->GetPosition()->GetShapeId();
+ TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID ));
+ if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(),
+ scalex, scaley, _quadraticMesh )) {
+ myNodesOnCommonV.push_back( mefistoToDS[m] );
+ continue;
+ }
+ }
+ // prevent failure on overlapped adjacent links,
+ // check only links ending in vertex nodes
+ int mB = m - 1, mA = m + 1; // indices Before and After
+ if ( mB < mFirst ) mB = mLast;
+ if ( mA > mLast ) mA = mFirst;
+ fixOverlappedLinkUV (uvslf[ mB ], uvslf[ m ], uvslf[ mA ]);
}
- } // for wexp
-
- // prevent failure on overlapped adjacent links,
- // check only links ending in vertex nodes
- int mFirst = mOnVertex.front(), mLast = m - 1;
- list< int >::iterator mIt = mOnVertex.begin();
- for ( ; mIt != mOnVertex.end(); ++mIt ) {
- int i = *mIt;
- int iB = i - 1, iA = i + 1; // indices Before and After
- if ( iB < mFirst ) iB = mLast;
- if ( iA > mLast ) iA = mFirst;
- fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
}
return true;
*/
//=============================================================================
-void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
- const TopoDS_Face & aFace, double &scalex, double &scaley)
+void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
+ const TopoDS_Face & aFace,
+ double & scalex,
+ double & scaley)
{
- //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
- TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
- TopoDS_Wire W = BRepTools::OuterWire(F);
+ TopoDS_Wire W = BRepTools::OuterWire(aFace);
double xmin = 1.e300; // min & max of face 2D parametric coord.
double xmax = -1.e300;
{
const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, aFace, f, l);
if ( C2d.IsNull() ) continue;
double du = (l - f) / double (nbp);
for (int i = 0; i <= nbp; i++)
double xsize = xmax - xmin;
double ysize = ymax - ymin;
- Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
+ TopLoc_Location L;
+ Handle(Geom_Surface) S = BRep_Tool::Surface(aFace,L); // 3D surface
double length_x = 0;
double length_y = 0;
*/
//=============================================================================
-void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
- Z nbst, R2 * uvst, Z nbt, Z * nust,
- const TopoDS_Face & F, bool faceIsForward,
- map<int, const SMDS_MeshNode*>&mefistoToDS,
+void StdMeshers_MEFISTO_2D::StoreResult(Z nbst, R2 * uvst, Z nbt, Z * nust,
+ vector< const SMDS_MeshNode*>&mefistoToDS,
double scalex, double scaley)
{
- SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- int faceID = meshDS->ShapeToIndex( F );
+ SMESHDS_Mesh * meshDS = myTool->GetMeshDS();
+ int faceID = myTool->GetSubShapeID();
- Z n, m;
- Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+ TopoDS_Face F = TopoDS::Face( myTool->GetSubShape() );
+ Handle(Geom_Surface) S = BRep_Tool::Surface( F );
- for (n = 0; n < nbst; n++)
+ Z n = mefistoToDS.size(); // nb input points
+ mefistoToDS.resize( nbst );
+ for ( ; n < nbst; n++)
{
- if (mefistoToDS.find(n + 1) == mefistoToDS.end())
+ if (!mefistoToDS[n])
{
double u = uvst[n][0] / scalex;
double v = uvst[n][1] / scaley;
meshDS->SetNodeOnFace(node, faceID, u, v);
//MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
- mefistoToDS[n + 1] = node;
+ mefistoToDS[n] = node;
//MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
}
}
- m = 0;
+ Z m = 0;
// triangle points must be in trigonometric order if face is Forward
// else they must be put clockwise
- bool triangleIsWellOriented = faceIsForward;
+ bool triangleIsWellOriented = ( F.Orientation() == TopAbs_FORWARD );
for (n = 1; n <= nbt; n++)
{
- const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
- const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
- const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
+ const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] - 1 ];
+ const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] - 1 ];
+ const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] - 1 ];
SMDS_MeshElement * elt;
if (triangleIsWellOriented)
- //elt = meshDS->AddFace(n1, n2, n3);
elt = myTool->AddFace(n1, n2, n3);
else
- //elt = meshDS->AddFace(n1, n3, n2);
elt = myTool->AddFace(n1, n3, n2);
meshDS->SetMeshElementOnShape(elt, faceID);
}
}
}
-
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape)
-{
- //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
- // **** a mettre dans SMESH_2D_Algo ?
-
- //const TopoDS_Face & FF = TopoDS::Face(aShape);
- //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
- //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
-
- double meanElementLength = 100;
- double wireLength = 0;
- int wireElementsNumber = 0;
- for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
- {
- const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
- int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- double length = EdgeLength(E);
- wireLength += length;
- wireElementsNumber += nb;
- }
- if (wireElementsNumber)
- meanElementLength = wireLength / wireElementsNumber;
- //SCRUTE(meanElementLength);
- return meanElementLength;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
-{
- return save;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
-{
- return load;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
-{
- return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
-{
- return hyp.LoadFrom( load );
}
#include "SMESH_StdMeshers.hxx"
#include "SMESH_2D_Algo.hxx"
-#include <TopoDS_Wire.hxx>
-#include "SMESH_MesherHelper.hxx"
-
-class SMDS_MeshNode;
-class TopTools_IndexedDataMapOfShapeListOfShape;
class TopoDS_Face;
-class TopoDS_WIre;
class StdMeshers_MaxElementArea;
class StdMeshers_LengthFromEdges;
class SMDS_MeshNode;
+class SMESH_MesherHelper;
+class StdMeshers_FaceSide;
+#include <vector>
#include <list>
-#include <map>
#include "Rn.h"
-class STDMESHERS_EXPORT StdMeshers_MEFISTO_2D:
- public SMESH_2D_Algo
+class STDMESHERS_EXPORT StdMeshers_MEFISTO_2D: public SMESH_2D_Algo
{
public:
StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen* gen);
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
- double ComputeEdgeElementLength(SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape);
+ typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
+ typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
- bool LoadPoints(SMESH_Mesh& aMesh,
- const TopoDS_Face& F,
- const TopoDS_Wire& W,
- R2* uvslf,
- int& m,
- map<int,const SMDS_MeshNode*>& mefistoToDS,
- double scalex, double scaley,
- const TopTools_IndexedDataMapOfShapeListOfShape& VWMap);
+ bool LoadPoints(TWireVector & wires,
+ R2* uvslf,
+ std::vector< const SMDS_MeshNode*>& mefistoToDS,
+ double scalex, double scaley);
void ComputeScaleOnFace(SMESH_Mesh& aMesh,
const TopoDS_Face& aFace,
double& scalex,
double& scaley);
- void StoreResult (SMESH_Mesh& aMesh,
- Z nbst, R2* uvst, Z nbt, Z* nust,
- const TopoDS_Face& F, bool faceIsForward,
- map<int,const SMDS_MeshNode*>& mefistoToDS,
+ void StoreResult (Z nbst, R2* uvst, Z nbt, Z* nust,
+ std::vector< const SMDS_MeshNode*>& mefistoToDS,
double scalex, double scaley);
- ostream & SaveTo(ostream & save);
- istream & LoadFrom(istream & load);
- friend ostream & operator << (ostream & save, StdMeshers_MEFISTO_2D & hyp);
- friend istream & operator >> (istream & load, StdMeshers_MEFISTO_2D & hyp);
-
protected:
double _edgeLength;
double _maxElementArea;
const StdMeshers_MaxElementArea* _hypMaxElementArea;
const StdMeshers_LengthFromEdges* _hypLengthFromEdges;
- TopoDS_Wire myOuterWire;
std::list<const SMDS_MeshNode*> myNodesOnCommonV;
SMESH_MesherHelper* myTool; // toll for working with quadratic elements
#include "SMESH_MeshEditor.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
//purpose :
//=======================================================================
StdMeshers_Penta_3D::StdMeshers_Penta_3D()
-: myErrorStatus(1)
+: myErrorStatus(SMESH_ComputeError::New())
{
myTol3D=0.1;
myWallNodesMaps.resize( SMESH_Block::NbFaces() );
StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
{
- if ( myTool )
- delete myTool;
}
//=======================================================================
{
MESSAGE("StdMeshers_Penta_3D::Compute()");
//
- myErrorStatus=0;
- //
bool bOK=false;
//
myShape=aShape;
SetMesh(aMesh);
//
CheckData();
- if (myErrorStatus){
+ if (!myErrorStatus->IsOK()) {
return bOK;
}
- myTool = new SMESH_MesherHelper(aMesh);
+ SMESH_MesherHelper helper(aMesh);
+ myTool = &helper;
myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
//
MakeBlock();
- if (myErrorStatus){
- delete myTool; myTool = 0;
+ if (!myErrorStatus->IsOK()) {
return bOK;
}
//
ClearMeshOnFxy1();
- if (myErrorStatus) {
- delete myTool; myTool = 0;
+ if (!myErrorStatus->IsOK()) {
return bOK;
}
//
MakeNodes();
- if (myErrorStatus){
- delete myTool; myTool = 0;
+ if (!myErrorStatus->IsOK()) {
return bOK;
}
//
MakeConnectingMap();
//
MakeMeshOnFxy1();
- if (myErrorStatus) {
- delete myTool; myTool = 0;
+ if (!myErrorStatus->IsOK()) {
return bOK;
}
//
MakeVolumeMesh();
//
- delete myTool; myTool = 0;
return !bOK;
}
//=======================================================================
void StdMeshers_Penta_3D::MakeNodes()
{
- myErrorStatus=0;
- //
const int aNbSIDs=9;
int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
double aX, aY, aZ;
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
"SMESHBlock: ComputeParameters operation failed");
- myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+ myErrorStatus=myBlock.GetError();
return;
}
aTNode.SetNormCoord(aCoords);
TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )),
pMesh->GetMeshDS());
if ( !ok ) {
- myErrorStatus = i + 1;
- MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus );
+ myErrorStatus->myName = COMPERR_BAD_INPUT_MESH;
+ myErrorStatus->myComment = SMESH_Comment() <<
+ "Can't find regular quadrangle mesh on a side face #" <<
+ pMesh->GetMeshDS()->ShapeToIndex( myBlock.Shape( wallFaceID[ i ]));
return;
}
}
//
// suporting shape ID
ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
return;
}
meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
}
}
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
return;
}
const int z,
StdMeshers_TNode& aTN)
{
- myErrorStatus=0;
- //
double aX, aY, aZ, aD, aTol2, minD;
gp_Pnt aP1, aP2;
//
//=======================================================================
void StdMeshers_Penta_3D::MakeVolumeMesh()
{
- myErrorStatus=0;
- //
int i, j, ij, ik, i1, i2, aSSID;
//
SMESH_Mesh* pMesh = GetMesh();
continue;
aID0 = pNode->GetID();
aJ[k] = GetIndexOnLayer(aID0);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
return;
}
//=======================================================================
void StdMeshers_Penta_3D::MakeMeshOnFxy1()
{
- myErrorStatus=0;
- //
int aID0, aJ, aLevel, ij, aNbNodes, k;
//
SMDS_NodeIteratorPtr itn;
k = aNbNodes-1; // reverse a face
aItNodes = pE0->nodesIterator();
while (aItNodes->more()) {
- //const SMDS_MeshElement* pNode = aItNodes->next();
const SMDS_MeshNode* pNode =
static_cast<const SMDS_MeshNode*> (aItNodes->next());
if(myTool->IsMedium(pNode))
continue;
aID0 = pNode->GetID();
aJ = GetIndexOnLayer(aID0);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
return;
}
//=======================================================================
void StdMeshers_Penta_3D::ClearMeshOnFxy1()
{
- myErrorStatus=0;
- //
SMESH_subMesh* aSubMesh;
SMESH_Mesh* pMesh=GetMesh();
//
//=======================================================================
int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
{
- myErrorStatus=0;
- //
int j=-1;
StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
//
aMapIt=myConnectingMap.find(aID);
if (aMapIt==myConnectingMap.end()) {
- myErrorStatus=200;
+ myErrorStatus->myName = 200;
+ myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
return j;
}
j=(*aMapIt).second;
const gp_XYZ& aParams,
StdMeshers_TNode& aTN)
{
- myErrorStatus=0;
- //
- // int iErr;
double aX, aY, aZ;
//
gp_Pnt aP;
const SMESH_Block::TShapeID aBNSSID,
SMESH_Block::TShapeID& aSSID)
{
- myErrorStatus=0;
- //
switch (aBNSSID) {
case SMESH_Block::ID_V000:
aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
break;
default:
aSSID=SMESH_Block::ID_NONE;
- myErrorStatus=10; // Can not find supporting shape ID
+ myErrorStatus->myName=10; // Can not find supporting shape ID
+ myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
break;
}
return;
//=======================================================================
void StdMeshers_Penta_3D::MakeBlock()
{
- myErrorStatus=0;
- //
bool bFound;
int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
//
}
}
if (!isOK) {
- myErrorStatus=5; // more than one face has triangulation
+ myErrorStatus->myName=5; // more than one face has triangulation
+ myErrorStatus->myComment="Incorrect input mesh";
return;
}
}
iNbE = aME.Extent();
if (iNbE!= NB_WALL_FACES ){
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=7; // too few edges are in base face aFTr
+ myErrorStatus->myName=7; // too few edges are in base face aFTr
+ myErrorStatus->myComment=SMESH_Comment("Not a quadrilateral face #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aFTr )<<": "<<iNbE<<" edges" ;
return;
}
const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
iNbEV=aMEV.Extent();
if (iNbEV!=3){
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=7; // too few edges meet in base vertex
+ myErrorStatus->myName=7; // too few edges meet in base vertex
+ myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<<iNbEV<<" edges";
return;
}
//
//
if (!bFound) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=8; // can not find reper V001
+ myErrorStatus->myName=8; // can not find reper V001
+ myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aV000 );
return;
}
//DEB
iNbE=aME.Extent();
if (iNbE!=1) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=9; // number of shells in source shape !=1
+ myErrorStatus->myName=9; // number of shells in source shape !=1
+ myErrorStatus->myComment=SMESH_Comment("Unexpected nb of shells ")<<iNbE;
return;
}
//
iErr = myBlock.ErrorStatus();
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=100; // SMESHBlock: Load operation failed
+ myErrorStatus=myBlock.GetError(); // SMESHBlock: Load operation failed
return;
}
}
//=======================================================================
void StdMeshers_Penta_3D::CheckData()
{
- myErrorStatus=0;
- //
int i, iNb;
int iNbEx[]={8, 12, 6};
//
//
if (myShape.IsNull()){
MESSAGE("StdMeshers_Penta_3D::CheckData() ");
- myErrorStatus=2; // null shape
+ myErrorStatus->myName=2; // null shape
+ myErrorStatus->myComment="Null shape";
return;
}
//
aST=myShape.ShapeType();
if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
MESSAGE("StdMeshers_Penta_3D::CheckData() ");
- myErrorStatus=3; // not compatible type of shape
+ myErrorStatus->myName=3; // not compatible type of shape
+ myErrorStatus->myComment=SMESH_Comment("Wrong shape type (TopAbs_ShapeEnum) ")<<aST;
return;
}
//
iNb=aM.Extent();
if (iNb!=iNbEx[i]){
MESSAGE("StdMeshers_Penta_3D::CheckData() ");
- myErrorStatus=4; // number of subshape is not compatible
+ myErrorStatus->myName=4; // number of subshape is not compatible
+ myErrorStatus->myComment="Wrong number of subshapes of a block";
return;
}
}
// try to load the rest nodes
// get all faces from theFace
- map<int,const SMDS_MeshElement*> allFaces, foundFaces;
+ TIDSortedElemSet allFaces, foundFaces;
SMDS_ElemIteratorPtr eIt = smFace->GetElements();
while ( eIt->more() ) {
const SMDS_MeshElement* e = eIt->next();
if ( e->GetType() == SMDSAbs_Face )
- allFaces.insert( make_pair(e->GetID(),e) );
+ allFaces.insert( e );
}
// Starting from 2 neighbour nodes on theBaseEdge, look for a face
// the nodes belong to, and between the nodes of the found face,
return false;
}
par_nVec_2->second[ row ] = node;
- foundFaces.insert( make_pair(face->GetID(),face) );
+ foundFaces.insert( face );
n2 = node;
if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) {
n1 = par_nVec_1->second[ row ];
return myErrorStatus;
}
+//================================================================================
+/*!
+ * \brief Return problem description
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const
+{
+ SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
+ string & text = err->myComment;
+ switch ( myErrorStatus ) {
+ case 2:
+ case 3: text = "Internal error of StdMeshers_Penta_3D"; break;
+ case 4: text = "Can't compute normalized parameters of a point inside a block"; break;
+ case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break;
+ case 6: text = "Can't detect block subshapes. Not a block?"; break;
+ }
+ if (!text.empty())
+ err->myName = myErrorStatus;
+ return err;
+}
+
//=======================================================================
//function : Load
//purpose :
myShapeIDMap.Clear();
bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
if (!bOk) {
- myErrorStatus=2;
+ myErrorStatus=6;
return;
}
}
}
}
if (!bOk) {
- myErrorStatus=4; // problems with point computation
+ myErrorStatus=5; // problems with point computation
return;
}
aP3D.SetXYZ(aXYZ);
#include <TColStd_MapOfInteger.hxx>
#include "SMESH_Block.hxx"
-
+#include "SMESH_ComputeError.hxx"
#include "SMESH_MesherHelper.hxx"
typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
int ErrorStatus() const;
+ SMESH_ComputeErrorPtr GetError() const;
+
protected:
TopoDS_Shell myShell;
bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
int ErrorStatus() const {
+ if (myErrorStatus->IsOK())
+ return 0;
+ return myErrorStatus->myName;
+ }
+
+ SMESH_ComputeErrorPtr GetComputeError() const {
return myErrorStatus;
}
TopoDS_Shape myShape;
StdMeshers_SMESHBlock myBlock;
void * myMesh;
- int myErrorStatus;
+ SMESH_ComputeErrorPtr myErrorStatus;
//
vector <StdMeshers_TNode> myTNodes;
int myISize;
vector<gp_XYZ> myShapeXYZ; // point on each sub-shape
bool myCreateQuadratic;
- SMESH_MesherHelper* myTool; // toll for working with quadratic elements
+ SMESH_MesherHelper* myTool; // tool building quadratic elements
};
#endif
#include "SMDS_VolumeTool.hxx"
#include "SMDS_VolumeOfNodes.hxx"
#include "SMDS_EdgePosition.hxx"
+#include "SMESH_Comment.hxx"
#include "utilities.h"
// }
typedef StdMeshers_ProjectionUtils TAssocTool;
+typedef SMESH_Comment TCom;
enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0,
ID_TOP_FACE = SMESH_Block::ID_Fxy1,
bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
{
- myHelper = new SMESH_MesherHelper( theMesh );
- // to delete helper at exit from Compute()
- std::auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
+ SMESH_MesherHelper helper( theMesh );
+ myHelper = &helper;
myHelper->IsQuadraticSubMesh( theShape );
// Analyse mesh and geomerty to find block subshapes and submeshes
if ( !myBlock.Init( myHelper, theShape ))
- return false;
+ return error( myBlock.GetError());
SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() );
gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ];
if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE ))
- RETURN_BAD_RESULT("ComputeParameters() on the top face failed");
+ return error(dfltErr(),TCom("Can't compute normalized parameters ")
+ << "for node " << column.back()->GetID()
+ << " on the face #"<< column.back()->GetPosition()->GetShapeId() );
// vertical loop
TNodeColumn::iterator columnNodes = column.begin();
// compute coords for a new node
gp_XYZ coords;
if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords ))
- RETURN_BAD_RESULT("SMESH_Block::ShellPoint() failed");
+ return error(dfltErr(),"Can't compute coordinates by normalized parameters");
// create a node
node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
// Create volumes
SMESHDS_SubMesh* smDS = myBlock.SubMeshDS( ID_BOT_FACE );
- if ( !smDS ) RETURN_BAD_RESULT("Null submesh");
+ if ( !smDS ) return error(COMPERR_BAD_INPUT_MESH, "Null submesh");
// loop on bottom mesh faces
SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
bot_column = myBotToColumnMap.find( n );
if ( bot_column == myBotToColumnMap.end() )
- RETURN_BAD_RESULT(" node column for a node not found");
+ return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
columns[ i ] = & bot_column->second;
}
else {
columns[ i ] = myBlock.GetNodeColumn( n );
if ( !columns[ i ] )
- RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+ return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
}
}
// create prisms
SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
if ( !botSMDS || botSMDS->NbElements() == 0 )
- RETURN_BAD_RESULT("Empty horiz submesh");
+ return error(dfltErr(),TCom("No elememts on face #") << botSM->GetId());
bool needProject = false;
if ( !topSMDS ||
botSMDS->NbNodes() != topSMDS->NbNodes())
{
if ( myBlock.HasNotQuadElemOnTop() )
- RETURN_BAD_RESULT("Different triangles on 2 sides");
+ return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+ <<" and #"<< topSM->GetId() << " seems different" );
needProject = true;
}
if ( 0/*needProject && !myProjectTriangles*/ )
- RETURN_BAD_RESULT("Need to project but not allowed");
+ return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+ <<" and #"<< topSM->GetId() << " seems different" );
+ ///RETURN_BAD_RESULT("Need to project but not allowed");
if ( needProject )
{
if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(),
topFace, myBlock.Mesh(),
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ return error(dfltErr(),TCom("Topology of faces #") << botSM->GetId()
+ <<" and #"<< topSM->GetId() << " seems different" );
- // Find matching nodes of in and out faces
+ // Find matching nodes of top and bottom faces
TNodeNodeMap n2nMap;
if ( ! TAssocTool::FindMatchingNodesOnFaces( botFace, myBlock.Mesh(),
topFace, myBlock.Mesh(),
shape2ShapeMap, n2nMap ))
- RETURN_BAD_RESULT("Different mesh on top and bottom faces");
+ return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+ <<" and #"<< topSM->GetId() << " seems different" );
// Fill myBotToColumnMap
// compute bottom node params
TNode bN( botNode );
if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
- RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+ return error(dfltErr(),TCom("Can't compute normalized parameters ")
+ << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
// create node column
TNode2ColumnMap::iterator bN_col =
myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
// compute bottom node params
TNode bN( botNode );
if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
- RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+ return error(dfltErr(),TCom("Can't compute normalized parameters ")
+ << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
// compute top node coords
gp_XYZ topXYZ; gp_XY topUV;
if ( !myBlock.FacePoint( ID_TOP_FACE, bN.GetParams(), topXYZ ) ||
!myBlock.FaceUV ( ID_TOP_FACE, bN.GetParams(), topUV ))
- RETURN_BAD_RESULT("SMESH_Block::FacePoint() on the top face failed");
+ return error(dfltErr(),TCom("Can't compute coordinates ")
+ << "by normalized parameters on the face #"<< topSM->GetId() );
SMDS_MeshNode * topNode = meshDS->AddNode( topXYZ.X(),topXYZ.Y(),topXYZ.Z() );
meshDS->SetNodeOnFace( topNode, topFaceID, topUV.X(), topUV.Y() );
// create node column
if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n );
if ( bot_column == myBotToColumnMap.end() )
- RETURN_BAD_RESULT(" node column for a node not found");
+ return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
nodes[ i ] = bot_column->second.back();
}
else {
const TNodeColumn* column = myBlock.GetNodeColumn( n );
if ( !column )
- RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+ return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
nodes[ i ] = column->back();
}
}
mySide = new TSideFace( sideFaces, params );
myHelper = helper;
- SMESHDS_Mesh* meshDS = myHelper->GetMesh()->GetMeshDS();
+ SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
SMESH_Block::init();
myShapeIDMap.Clear();
SMESH_Block::ID_Fx1z, SMESH_Block::ID_F0yz
};
+ myError = SMESH_ComputeError::New();
+
// -------------------------------------------------------------
// Look for top and bottom faces: not quadrangle ones or meshed
// with not quadrangle elements
int nbFaces = 0;
//
SMESH_subMesh* mainSubMesh = myHelper->GetMesh()->GetSubMeshContaining( shape3D );
- if ( !mainSubMesh ) RETURN_BAD_RESULT("Null submesh of shape3D");
- //
- const map< int, SMESH_subMesh * >& subSM = mainSubMesh->DependsOn();
- map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
- for ( ; i_subSM != subSM.end(); ++i_subSM )
+ if ( !mainSubMesh ) return error(COMPERR_BAD_INPUT_MESH,"Null submesh of shape3D");
+
+ // analyse face submeshes
+ SMESH_subMeshIteratorPtr smIt = mainSubMesh->getDependsOnIterator(false,false);
+ while ( smIt->more() )
{
- SMESH_subMesh* sm = i_subSM->second;
+ SMESH_subMesh* sm = smIt->next();
const TopoDS_Shape& face = sm->GetSubShape();
if ( face.ShapeType() != TopAbs_FACE )
continue;
nbFaces++;
// is quadrangle face?
- if ( TAssocTool::Count( face, TopAbs_EDGE, 0 ) != 4 ||
- TAssocTool::Count( face, TopAbs_WIRE, 0 ) != 1 )
+ list< TopoDS_Edge > orderedEdges;
+ list< int > nbEdgesInWires;
+ TopoDS_Vertex V000;
+ int nbWires = GetOrderedEdges( TopoDS::Face( face ),
+ V000, orderedEdges, nbEdgesInWires );
+ if ( nbWires != 1 || nbEdgesInWires.front() != 4 )
notQuadGeomSubMesh.push_back( sm );
- // count not quadrangle mesh elements
+ // look for not quadrangle mesh elements
if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() ) {
- SMDS_ElemIteratorPtr eIt = smDS->GetElements();
bool hasNotQuad = false;
+ SMDS_ElemIteratorPtr eIt = smDS->GetElements();
while ( eIt->more() && !hasNotQuad ) {
const SMDS_MeshElement* elem = eIt->next();
if ( elem->GetType() == SMDSAbs_Face ) {
notQuadElemSubMesh.push_back( sm );
}
else {
- RETURN_BAD_RESULT("not meshed face");
+ return error(COMPERR_BAD_INPUT_MESH,TCom("Not meshed face #")<<sm->GetId());
+ }
+ // check if a quadrangle face is meshed with a quadranglar grid
+ if ( notQuadGeomSubMesh.back() != sm &&
+ notQuadElemSubMesh.back() != sm )
+ {
+ // count nb edges on face sides
+ vector< int > nbEdges;
+ nbEdges.reserve( nbEdgesInWires.front() );
+ for ( list< TopoDS_Edge >::iterator edge = orderedEdges.begin();
+ edge != orderedEdges.end(); ++edge )
+ {
+ if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edge ))
+ nbEdges.push_back ( smDS->NbElements() );
+ else
+ nbEdges.push_back ( 0 );
+ }
+ int nbQuads = sm->GetSubMeshDS()->NbElements();
+ if ( nbEdges[0] * nbEdges[1] != nbQuads ||
+ nbEdges[0] != nbEdges[2] ||
+ nbEdges[1] != nbEdges[3] )
+ notQuadElemSubMesh.push_back( sm );
}
}
// detect bad cases
if ( nbNotQuad > 0 && nbNotQuad != 2 )
- RETURN_BAD_RESULT("Wrong shape geometry");
+ return error(COMPERR_BAD_SHAPE,
+ TCom("More than 2 not quadrilateral faces")
+ <<nbNotQuad);
if ( nbNotQuadMeshed > 2 )
- RETURN_BAD_RESULT("More then 2 faces meshed with not quadrangle elements");
+ return error(COMPERR_BAD_INPUT_MESH,
+ TCom("More then 2 faces meshed with not quadrangle elements")
+ <<nbNotQuadMeshed);
// get found submeshes
if ( hasNotQuad )
else
ok = ( notQuadGeomSubMesh == notQuadElemSubMesh );
if ( !ok )
- RETURN_BAD_RESULT("Side face meshed with not quadrangle elements");
+ return error(COMPERR_BAD_INPUT_MESH, "Side face meshed with not quadrangle elements");
}
myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
-
+
// ----------------------------------------------------------
if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ?
const TopoDS_Shape & ancestor = ancestIt.Value();
if ( ancestor.ShapeType() == TopAbs_EDGE && !edgeMap.FindIndex( ancestor ))
{
- Vtop = TopExp::LastVertex( TopoDS::Edge( ancestor ));
- if ( Vbot.IsSame ( Vtop ))
- Vtop = TopExp::FirstVertex( TopoDS::Edge( ancestor ));
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices( TopoDS::Edge( ancestor ), V1, V2);
+ if ( Vbot.IsSame ( V1 )) Vtop = V2;
+ else if ( Vbot.IsSame ( V2 )) Vtop = V1;
+ // check that Vtop belongs to shape3D
+ TopExp_Explorer exp( shape3D, TopAbs_VERTEX );
+ for ( ; exp.More(); exp.Next() )
+ if ( Vtop.IsSame( exp.Current() ))
+ break;
+ if ( !exp.More() )
+ Vtop.Nullify();
}
}
}
// Load geometry in SMESH_Block
if ( !SMESH_Block::FindBlockShapes( shell, Vbot, Vtop, myShapeIDMap )) {
if ( !hasNotQuad )
- RETURN_BAD_RESULT("Can not detect top and bottom");
+ return error(COMPERR_BAD_SHAPE, "Can't detect top and bottom of a prism");
}
else {
if ( !botSM ) botSM = Mesh()->GetSubMeshContaining( myShapeIDMap( ID_BOT_FACE ));
// Get Wall faces corresponding to the ordered bottom edges
list< TopoDS_Face > wallFaces;
if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces))
- RETURN_BAD_RESULT("GetWallFaces() failed");
+ return error(COMPERR_BAD_SHAPE, "Can't find side faces");
// Find columns of wall nodes and calculate edges' lengths
// --------------------------------------------------------
{
TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
- RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+ return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+ << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
SHOWYXZ("\np1 F "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
{
SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edgeIt);
if ( !smDS )
- RETURN_BAD_RESULT("Null submesh on a bottom edge");
+ return error(COMPERR_BAD_INPUT_MESH, TCom("Null submesh on the edge #")
+ << MeshDS()->ShapeToIndex( *edgeIt ));
// assure length uniqueness
edgeLength[ iE ] *= smDS->NbNodes() + edgeLength[ iE ] / ( 1000 + iE );
len2edgeMap[ edgeLength[ iE ]] = iE;
{
TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
- RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+ return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+ << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
// edge columns
int id = MeshDS()->ShapeToIndex( *edgeIt );
bool isForward = true; // meaningless for intenal wires
}
default:;
}
- if ( !edge.IsNull() || edge.ShapeType() == TopAbs_EDGE )
+ if ( !edge.IsNull() && edge.ShapeType() == TopAbs_EDGE )
return TopoDS::Edge( edge );
// find edge by 2 vertices
#include "SMESHDS_Mesh.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
#include <vector>
*/
bool Init(SMESH_MesherHelper* helper, const TopoDS_Shape& shape3D);
+ /*!
+ * \brief Return problem description
+ */
+ SMESH_ComputeErrorPtr GetError() const { return myError; }
+
/*!
* \brief Return number of nodes on every vertical edge
* \retval int - number of nodes including end nodes
// to find a column for a node by edge SMESHDS Index
map< int, pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap;
-
+ SMESH_ComputeErrorPtr myError;
+ /*!
+ * \brief store error and comment and then return ( error == COMPERR_OK )
+ */
+ bool error(int error, const SMESH_Comment& comment = "") {
+ myError = SMESH_ComputeError::New(error,comment);
+ return myError->IsOK();
+ }
//vector< SMESH_subMesh* > mySubMeshesVec; // submesh by in-block id
};
#include "SMESH_Mesh.hxx"
#include "SMESH_MeshEditor.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
#include "SMDS_EdgePosition.hxx"
#include "utilities.h"
const SMDS_MeshElement* faceToKeep = 0;
const SMDS_MeshNode* vNode = is2 ? vNode2 : vNode1;
const SMDS_MeshNode* eNode = is2 ? eNode2[0] : eNode1[0];
- std::map<int,const SMDS_MeshElement*> inSet, notInSet;
+ TIDSortedElemSet inSet, notInSet;
const SMDS_MeshElement* f1 =
SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet );
if ( !f1 ) RETURN_BAD_RESULT("The first face on seam not found");
- SMESH_MeshEditor::Insert( f1, notInSet );
+ notInSet.insert( f1 );
const SMDS_MeshElement* f2 =
SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet );
//================================================================================
/*!
- * \brief Check that submeshis is computed and try to compute it if is not
+ * \brief Check that submesh is computed and try to compute it if is not
* \param sm - submesh to compute
* \param iterationNb - int used to stop infinite recursive call
* \retval bool - true if computed
}
}
- // bull shit
-// Standard_Real f1,l1, f2,l2;
-// BRep_Tool::Range( edge1, f1,l1 );
-// BRep_Tool::Range( edge2, f2,l2 );
-// BRepAdaptor_Curve e1( edge1 ), e2( edge2 );
-// gp_Pnt pf1, pf2;
-// gp_Vec dirX1, dirX2; // 1st derivatives
-// e1.D1( f1, pf1, dirX1 );
-// e2.D1( f2, pf2, dirX2 );
-// gp_Pnt pm1 = e1.Value( 0.5 * ( f1 + l1 ));
-// gp_Pnt pm2 = e2.Value( 0.5 * ( f2 + l2 ));
-// gp_Vec dirZ1( pf1, pm1 ), dirZ2( pf2, pm2 );
-// gp_Trsf trsf;
-// gp_Ax3 fromSys( pf1, dirZ1, dirX1 ), toSys( pf2, dirZ2, dirX2 );
-// trsf.SetTransformation( fromSys, toSys );
-// dirX1.Transform( trsf );
-// bool reverse = ( dirX1 * dirX2 < 0 );
-// if ( reverse ) edge2.Reverse();
+namespace {
+
+ SMESH_subMeshEventListener* GetSrcSubMeshListener();
+
+ //================================================================================
+ /*!
+ * \brief Listener that resets an event listener on source submesh when
+ * "ProjectionSource*D" hypothesis is modified
+ */
+ //================================================================================
+
+ struct HypModifWaiter: SMESH_subMeshEventListener
+ {
+ HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh
+
+ void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+ EventListenerData*, const SMESH_Hypothesis*)
+ {
+ if ( event == SMESH_subMesh::MODIF_HYP &&
+ eventType == SMESH_subMesh::ALGO_EVENT)
+ {
+ // delete current source listener
+ subMesh->DeleteEventListener( GetSrcSubMeshListener() );
+ // let algo set a new one
+ SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+ if ( SMESH_Algo* algo = gen->GetAlgo( *subMesh->GetFather(),
+ subMesh->GetSubShape() ))
+ algo->SetEventListener( subMesh );
+ }
+ }
+ };
+ //================================================================================
+ /*!
+ * \brief return static HypModifWaiter
+ */
+ //================================================================================
+
+ SMESH_subMeshEventListener* GetHypModifWaiter() {
+ static HypModifWaiter aHypModifWaiter;
+ return &aHypModifWaiter;
+ }
+ //================================================================================
+ /*!
+ * \brief return static listener for source shape submeshes
+ */
+ //================================================================================
+
+ SMESH_subMeshEventListener* GetSrcSubMeshListener() {
+ static SMESH_subMeshEventListener srcListener(0); // won't be deleted by submesh
+ return &srcListener;
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Set event listeners to submesh with projection algo
+ * \param subMesh - submesh with projection algo
+ * \param srcShape - source shape
+ * \param srcMesh - source mesh
+ */
+//================================================================================
+
+void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh,
+ TopoDS_Shape srcShape,
+ SMESH_Mesh* srcMesh)
+{
+ // Set listener that resets an event listener on source submesh when
+ // "ProjectionSource*D" hypothesis is modified
+ subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh);
+
+ // Set an event listener to submesh of the source shape
+ if ( !srcShape.IsNull() )
+ {
+ if ( !srcMesh )
+ srcMesh = subMesh->GetFather();
+
+ SMESH_subMesh* srcShapeSM = srcMesh->GetSubMesh( srcShape );
+
+ if ( srcShapeSM != subMesh )
+ subMesh->SetEventListener( GetSrcSubMeshListener(),
+ SMESH_subMeshEventListenerData::MakeData( subMesh ),
+ srcShapeSM );
+ }
+}
static int Count(const TopoDS_Shape& shape,
const TopAbs_ShapeEnum type,
const bool ignoreSame);
+
+ /*!
+ * \brief Set event listeners to submesh with projection algo
+ * \param subMesh - submesh with projection algo
+ * \param srcShape - source shape
+ * \param srcMesh - source mesh
+ */
+ static void SetEventListener(SMESH_subMesh* subMesh,
+ TopoDS_Shape srcShape,
+ SMESH_Mesh* srcMesh);
};
#endif
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen.hxx"
+#include "SMESH_Comment.hxx"
#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh,
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ return error(dfltErr(),SMESH_Comment("Vertices association failed" ));
// ----------------------------------------------
// Assure that mesh on a source edge is computed
if ( tgtMesh == srcMesh ) {
if ( !TAssocTool::MakeComputed( srcSubMesh ))
- RETURN_BAD_RESULT("Impossible to compute the source mesh");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
else {
if ( !srcSubMesh->IsMeshComputed() )
- RETURN_BAD_RESULT("Source mesh is not computed");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
// -----------------------------------------------
// Find out nodes distribution on the source edge
vector< double > params; // sorted parameters of nodes on the source edge
if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
- RETURN_BAD_RESULT("Bad node params on the source edge");
+ return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
int i, nbNodes = params.size();
vector< const SMDS_MeshNode* > nodes ( nbNodes );
// Get the first and last nodes
- // -----------------------------
-
- SMESHDS_SubMesh* smV0 = meshDS->MeshElements( tgtV[0] );
- SMESHDS_SubMesh* smV1 = meshDS->MeshElements( tgtV[1] );
- if ( !smV0 || !smV1 )
- RETURN_BAD_RESULT("No submeshes on vertices");
-
- SMDS_NodeIteratorPtr nItV0 = smV0->GetNodes();
- SMDS_NodeIteratorPtr nItV1 = smV1->GetNodes();
- if ( !nItV0->more() || !nItV1->more() )
- RETURN_BAD_RESULT("No nodes on vertices");
-
- nodes.front() = nItV0->next();
- nodes.back() = nItV1->next();
+ nodes.front() = VertexNode( tgtV[0], meshDS );
+ nodes.back() = VertexNode( tgtV[1], meshDS );
+ if ( !nodes.front() || !nodes.back() )
+ return error(COMPERR_BAD_INPUT_MESH,"No node on vertex");
// Compute parameters on the target edge and make internal nodes
// --------------------------------------------------------------
// from the point at given parameter.
GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] );
if ( !Discret.IsDone() )
- RETURN_BAD_RESULT(" GCPnts_AbscissaPoint failed");
+ return error(dfltErr(),"GCPnts_AbscissaPoint failed");
tgtParams[ i ] = Discret.Parameter();
}
// make internal nodes
}
// enough nodes to make all edges quadratic?
if ( quadratic && ( nbNodes < 3 || ( nbNodes % 2 != 1 )))
- RETURN_BAD_RESULT("Wrong nb nodes to make quadratic mesh");
+ return error(COMPERR_BAD_INPUT_MESH,
+ SMESH_Comment("Wrong number of nodes to make quadratic mesh: ")<<nbNodes);
// Create edges
// -------------
void StdMeshers_Projection_1D::SetEventListener(SMESH_subMesh* subMesh)
{
- if ( _sourceHypo && ! _sourceHypo->GetSourceEdge().IsNull() )
- {
- SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
- if ( !srcMesh )
- srcMesh = subMesh->GetFather();
-
- SMESH_subMesh* srcEdgeSM =
- srcMesh->GetSubMesh( _sourceHypo->GetSourceEdge() );
-
- if ( srcEdgeSM != subMesh )
- subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
- SMESH_subMeshEventListenerData::MakeData( subMesh ),
- srcEdgeSM );
- }
+ TAssocTool::SetEventListener( subMesh,
+ _sourceHypo->GetSourceEdge(),
+ _sourceHypo->GetSourceMesh() );
}
-
#include "SMESH_Pattern.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_EdgePosition.hxx"
#include "utilities.h"
// do not break but iterate over DependsOn()
}
default:
- const map< int, SMESH_subMesh * >& subSM = sm->DependsOn();
- map< int, SMESH_subMesh * >::const_iterator i_sm = subSM.begin();
- for ( ; i_sm != subSM.end(); ++i_sm )
- Clean( i_sm->second );
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ Clean( smIt->next() );
}
}
};
TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcFace, srcMesh,
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
// ----------------------------------------------
// Assure that mesh on a source Face is computed
if ( tgtMesh == srcMesh ) {
if ( !TAssocTool::MakeComputed( srcSubMesh ))
- RETURN_BAD_RESULT("Impossible to compute the source mesh");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
else {
if ( !srcSubMesh->IsMeshComputed() )
- RETURN_BAD_RESULT("Source mesh is not computed");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
// --------------------
SMESH_Pattern mapper;
mapper.Load( srcMesh, srcFace );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::Load() failed");
+ return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
// Find the first target vertex corresponding to first vertex of the <mapper>
// and <theReverse> flag needed to call mapper.Apply()
mapper.Apply( tgtFace, tgtV1, reverse );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::Apply() failed");
+ return error(dfltErr(),"Can't apply source mesh pattern to the face");
// Create the mesh
const bool toCreatePolygons = false, toCreatePolyedrs = false;
mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::MakeMesh() failed");
+ return error(dfltErr(),"Can't make mesh by source mesh pattern");
// it will remove mesh built by pattern mapper on edges and vertices
// in failure case
// Make groups of nodes to merge
// loop on edge and vertex submeshes of a target face
- const map< int, SMESH_subMesh * >& subSM = tgtSubMesh->DependsOn();
- map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
- for ( ; i_subSM != subSM.end(); ++i_subSM )
+ SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false);
+ while ( smIt->more() )
{
- SMESH_subMesh* sm = i_subSM->second;
+ SMESH_subMesh* sm = smIt->next();
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
// Sort new and old nodes of a submesh separately
void StdMeshers_Projection_2D::SetEventListener(SMESH_subMesh* subMesh)
{
- if ( _sourceHypo && ! _sourceHypo->GetSourceFace().IsNull() )
- {
- SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
- if ( !srcMesh )
- srcMesh = subMesh->GetFather();
-
- SMESH_subMesh* srcFaceSM =
- srcMesh->GetSubMesh( _sourceHypo->GetSourceFace() );
-
- subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
- SMESH_subMeshEventListenerData::MakeData( subMesh ),
- srcFaceSM );
- }
+ TAssocTool::SetEventListener( subMesh,
+ _sourceHypo->GetSourceFace(),
+ _sourceHypo->GetSourceMesh() );
}
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
srcShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
- RETURN_BAD_RESULT("There must be 1 shell in the source shape");
+ return error(COMPERR_BAD_SHAPE,
+ SMESH_Comment("Shape must have 1 shell but not") << nbShell);
exp.Init( aShape, TopAbs_SHELL );
for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
tgtShell = TopoDS::Shell( exp.Current() );
if ( nbShell != 1 )
- RETURN_BAD_RESULT("There must be 1 shell in the target shape");
+ return error(COMPERR_BAD_SHAPE,
+ SMESH_Comment("Shape must have 1 shell but not") << nbShell);
// Assure that mesh on a source shape is computed
if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) {
if ( !TAssocTool::MakeComputed( srcSubMesh ))
- RETURN_BAD_RESULT("Impossible to compute the source mesh");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
else {
if ( !srcSubMesh->IsMeshComputed() )
- RETURN_BAD_RESULT("Source mesh is not computed");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
// Find 2 pairs of corresponding vertices
{
if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh,
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation() failed");
+ return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" );
exp.Init( tgtShell, TopAbs_EDGE );
TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );
if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
- RETURN_BAD_RESULT("Shape associating not done");
+ return error(dfltErr(),"Association of subshapes failed" );
srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
if ( !TAssocTool::IsSubShape( srcV000, srcShell ) ||
!TAssocTool::IsSubShape( srcV100, srcShell ))
- RETURN_BAD_RESULT("Wrong target vertices");
+ return error(dfltErr(),"Incorrect association of subshapes" );
}
// Load 2 SMESH_Block's with src and tgt shells
SMESH_Block srcBlock, tgtBlock;
TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
- RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(tgtShell) failed");
+ return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
- RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(srcShell) failed");
+ return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
// Find matching nodes of src and tgt shells
TNodeNodeMap faceMatchingNodes;
if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh,
shape2ShapeMap, faceMatchingNodes ))
- RETURN_BAD_RESULT("Different mesh on corresponding src and tgt faces: "
- << srcMeshDS->ShapeToIndex( srcFace ) << " and "
- << tgtMeshDS->ShapeToIndex( tgtFace ));
+ return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+ << srcMeshDS->ShapeToIndex( srcFace ) << " and "
+ << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
// put found matching nodes of 2 faces to the global map
src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
gp_Pnt srcCoord = gpXYZ( srcNode );
gp_XYZ srcParam;
if ( !srcBlock.ComputeParameters( srcCoord, srcParam ))
- RETURN_BAD_RESULT("srcBlock.ComputeParameters() failed");
+ return error(dfltErr(),SMESH_Comment("Can't compute normalized parameters ")
+ << "for source node " << srcNode->GetID());
// compute coordinates of target node by srcParam
gp_XYZ tgtXYZ;
if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ ))
- RETURN_BAD_RESULT("tgtBlock.ShellPoint() failed");
+ return error(dfltErr(),"Can't compute coordinates by normalized parameters");
// add node
SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() );
tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() );
// Create a new volume
SMDS_MeshVolume * tgtVol = 0;
+ int id = 0, force3d = false;
switch ( volType ) {
case SMDS_VolumeTool::TETRA :
case SMDS_VolumeTool::QUAD_TETRA:
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
- nodes[3]); break;
+ nodes[3], id, force3d); break;
case SMDS_VolumeTool::PYRAM :
case SMDS_VolumeTool::QUAD_PYRAM:
tgtVol = helper.AddVolume( nodes[0],
nodes[1],
nodes[2],
nodes[3],
- nodes[4]); break;
+ nodes[4], id, force3d); break;
case SMDS_VolumeTool::PENTA :
case SMDS_VolumeTool::QUAD_PENTA:
tgtVol = helper.AddVolume( nodes[0],
nodes[2],
nodes[3],
nodes[4],
- nodes[5]); break;
+ nodes[5], id, force3d); break;
case SMDS_VolumeTool::HEXA :
case SMDS_VolumeTool::QUAD_HEXA :
tgtVol = helper.AddVolume( nodes[0],
nodes[4],
nodes[5],
nodes[6],
- nodes[7]); break;
+ nodes[7], id, force3d); break;
default: // polyhedron
const SMDS_PolyhedralVolumeOfNodes * poly =
dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
if ( !poly )
RETURN_BAD_RESULT("Unexpected volume type");
- vector<int> quantities( poly->NbFaces(), 0 );
- for ( int i = 0; i < quantities.size(); ++i )
- quantities[ i ] = poly->NbFaceNodes( i + 1 );
- tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, quantities );
+ tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
}
if ( tgtVol ) {
tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
{
- if ( _sourceHypo && ! _sourceHypo->GetSource3DShape().IsNull() )
- {
- SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
- if ( !srcMesh )
- srcMesh = subMesh->GetFather();
-
- SMESH_subMesh* srcShapeSM =
- srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
-
- if ( srcShapeSM != subMesh )
- subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
- SMESH_subMeshEventListenerData::MakeData( subMesh ),
- srcShapeSM );
- }
+ TAssocTool::SetEventListener( subMesh,
+ _sourceHypo->GetSource3DShape(),
+ _sourceHypo->GetSourceMesh() );
}
#include "utilities.h"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMDS_SetIterator.hxx"
+
using namespace std;
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId,
- SMESH_Gen * gen)
- : SMESH_Hypothesis(hypId, studyId, gen)
-{
- _name = GetName();
- _param_algo_dim = -1; // 1D auxiliary
-}
+namespace {
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::~StdMeshers_Propagation()
-{
+ // =======================================================================
+ /*!
+ * \brief Listener managing propagation of 1D hypotheses
+ */
+ // =======================================================================
+
+ class PropagationMgr: public SMESH_subMeshEventListener
+ {
+ public:
+ static PropagationMgr* GetListener();
+ /*!
+ * \brief Set listener on edge submesh
+ */
+ static void Set(SMESH_subMesh * submesh);
+ /*!
+ * \brief Return an edge from which hypotheses are propagated from
+ */
+ static TopoDS_Edge GetSource(SMESH_subMesh * submesh);
+ /*!
+ * \brief Does it's main job
+ */
+ void ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ SMESH_subMeshEventListenerData* data,
+ const SMESH_Hypothesis* hyp = 0);
+ private:
+ PropagationMgr();
+ };
}
//=============================================================================
/*!
- *
+ * StdMeshers_Propagation Implementation
*/
//=============================================================================
-ostream & StdMeshers_Propagation::SaveTo (ostream & save)
+StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Gen * gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
{
- return save;
+ _name = GetName();
+ _param_algo_dim = -1; // 1D auxiliary
}
-
-//=============================================================================
+StdMeshers_Propagation::~StdMeshers_Propagation() {}
+string StdMeshers_Propagation::GetName () { return "Propagation"; }
+ostream & StdMeshers_Propagation::SaveTo (ostream & save) { return save; }
+istream & StdMeshers_Propagation::LoadFrom (istream & load) { return load; }
+ostream & operator << (ostream & save, StdMeshers_Propagation & hyp) { return hyp.SaveTo(save); }
+istream & operator >> (istream & load, StdMeshers_Propagation & hyp) { return hyp.LoadFrom(load); }
+bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*,
+ const TopoDS_Shape& ) { return false; }
+void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); }
/*!
- *
+ * \brief Return an edge from which hypotheses are propagated from
*/
-//=============================================================================
-istream & StdMeshers_Propagation::LoadFrom (istream & load)
+TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theEdge)
{
- return load;
+ return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
}
//=============================================================================
-/*!
- *
- */
//=============================================================================
-ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)
-{
- return hyp.SaveTo(save);
-}
-
+// PROPAGATION MANAGEMENT
//=============================================================================
-/*!
- *
- */
//=============================================================================
-istream & operator >> (istream & load, StdMeshers_Propagation & hyp)
-{
- return hyp.LoadFrom(load);
-}
-//=============================================================================
-/*!
- * GetName
- */
-//=============================================================================
-std::string StdMeshers_Propagation::GetName ()
-{
- return "Propagation";
-}
-//================================================================================
-/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as this hypothesis does not have parameters values
- */
-//================================================================================
+namespace {
-bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
- const TopoDS_Shape& /*theShape*/)
-{
- return false;
-}
+ enum SubMeshState { WAIT_PROPAG_HYP, // no propagation hyp in chain
+ HAS_PROPAG_HYP, // propag hyp on this submesh
+ IN_CHAIN, // submesh is in propagation chain
+ LAST_IN_CHAIN, // submesh with local 1D hyp breaking a chain
+ MEANINGLESS_LAST }; // meaningless
+
+ struct PropagationMgrData : public EventListenerData
+ {
+ bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge
+ PropagationMgrData( SubMeshState state ): EventListenerData(true) {
+ myType = state;
+ }
+ SubMeshState State() const {
+ return (SubMeshState) myType;
+ }
+ void SetSource(SMESH_subMesh* sm ) {
+ mySubMeshes.clear(); if ( sm ) mySubMeshes.push_back( sm );
+ }
+ void SetChain(list< SMESH_subMesh* >& chain ) {
+ mySubMeshes.clear(); mySubMeshes.splice( mySubMeshes.end(), chain );
+ }
+ SMESH_subMeshIteratorPtr GetChain() const;
+ SMESH_subMesh* GetSource() const;
+ };
+
+ //=============================================================================
+ /*!
+ * \brief return filter to find Propagation hypothesis
+ */
+ SMESH_HypoFilter & propagHypFilter()
+ {
+ static SMESH_HypoFilter propagHypFilter
+ ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ()));
+ return propagHypFilter;
+ }
+ //=============================================================================
+ /*!
+ * \brief return static PropagationMgr
+ */
+ PropagationMgr* PropagationMgr::GetListener()
+ {
+ static PropagationMgr theListener;
+ return &theListener;
+ }
+ PropagationMgr* getListener()
+ {
+ return PropagationMgr::GetListener();
+ }
+ //=============================================================================
+ /*!
+ * \brief return PropagationMgrData
+ */
+ PropagationMgrData* getData(SMESH_subMesh* sm)
+ {
+ if ( sm )
+ return static_cast< PropagationMgrData* >( sm->GetEventListenerData( getListener() ));
+ return 0;
+ }
+ //=============================================================================
+ /*!
+ * \brief return PropagationMgrData
+ */
+ PropagationMgrData* getData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge)
+ {
+ if ( theEdge.ShapeType() == TopAbs_EDGE )
+ return getData( theMesh.GetSubMeshContaining( theEdge ) );
+ return 0;
+ }
+ //================================================================================
+ /*!
+ * \brief Return an iterator on a chain
+ */
+ SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const
+ {
+ typedef SMESH_subMesh* TsubMesh;
+ typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator;
+ switch ( State() ) {
+ case HAS_PROPAG_HYP:
+ return SMESH_subMeshIteratorPtr
+ ( new TIterator( mySubMeshes.begin(), mySubMeshes.end() ));
+ case IN_CHAIN:
+ case LAST_IN_CHAIN:
+ if ( mySubMeshes.empty() ) break;
+ return getData( mySubMeshes.front() )->GetChain();
+ default:;
+ }
+ return SMESH_subMeshIteratorPtr
+ ( new TIterator( mySubMeshes.end(), mySubMeshes.end() ));
+ }
+ //================================================================================
+ /*!
+ * \brief Return a propagation source submesh
+ */
+ SMESH_subMesh* PropagationMgrData::GetSource() const
+ {
+ if ( myType == IN_CHAIN || myType == LAST_IN_CHAIN )
+ if ( !mySubMeshes.empty() )
+ return mySubMeshes.front();
+ return 0;
+ }
+ //=============================================================================
+ /*!
+ * \brief Returns a local 1D hypothesis used for theEdge
+ */
+ const SMESH_Hypothesis* isLocal1DHypothesis (SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theEdge)
+ {
+ static SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 ));
+ hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() ));
+
+ return theMesh.GetHypothesis( theEdge, hypo, true );
+ }
+ //================================================================================
+ /*!
+ * \brief Build propagation chain
+ * \param theMainSubMesh - the submesh with Propagation hypothesis
+ */
+ bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh )
+ {
+ // const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape();
+// if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
+
+// SMESH_Mesh* mesh = theMainSubMesh->GetFather();
+
+// EventListenerData* chainData = new PropagationMgrData(HAS_PROPAG_HYP);
+// theMainSubMesh->SetEventListener( getListener(), chainData, theMainSubMesh );
+
+// // Edges submeshes, on which the 1D hypothesis will be propagated from <theMainEdge>
+// list<SMESH_subMesh*> & chain = chainData->mySubMeshes;
+
+// // List of edges, added to chain on the previous cycle pass
+// TopTools_ListOfShape listPrevEdges;
+// listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
+
+// // 4____3____2____3____4____5
+// // | | | | | | Number in the each knot of
+// // | | | | | | grid indicates cycle pass,
+// // 3____2____1____2____3____4 on which corresponding edge
+// // | | | | | | (perpendicular to the plane
+// // | | | | | | of view) will be found.
+// // 2____1____0____1____2____3
+// // | | | | | |
+// // | | | | | |
+// // 3____2____1____2____3____4
+
+// // Collect all edges pass by pass
+// while (listPrevEdges.Extent() > 0) {
+// // List of edges, added to chain on this cycle pass
+// TopTools_ListOfShape listCurEdges;
+
+// // Find the next portion of edges
+// TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
+// for (; itE.More(); itE.Next()) {
+// TopoDS_Shape anE = itE.Value();
+
+// // Iterate on faces, having edge <anE>
+// TopTools_ListIteratorOfListOfShape itA (mesh->GetAncestors(anE));
+// for (; itA.More(); itA.Next()) {
+// TopoDS_Shape aW = itA.Value();
+
+// // There are objects of different type among the ancestors of edge
+// if (aW.ShapeType() == TopAbs_WIRE) {
+// TopoDS_Shape anOppE;
+
+// BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
+// Standard_Integer nb = 1, found = 0;
+// TopTools_Array1OfShape anEdges (1,4);
+// for (; aWE.More(); aWE.Next(), nb++) {
+// if (nb > 4) {
+// found = 0;
+// break;
+// }
+// anEdges(nb) = aWE.Current();
+// if (!_mapAncestors.Contains(anEdges(nb))) {
+// MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
+// break;
+// }
+// if (anEdges(nb).IsSame(anE)) found = nb;
+// }
+
+// if (nb == 5 && found > 0) {
+// // Quadrangle face found, get an opposite edge
+// Standard_Integer opp = ( found + 2 ) % 4;
+// anOppE = anEdges(opp);
+
+// // add anOppE to aChain if ...
+// PropagationMgrData* data = getData( *mesh, anOppE );
+// if ( !data || data->State() == WAIT_PROPAG_HYP ) { // ... anOppE is not in any chain
+// if ( !isLocal1DHypothesis( *mesh, anOppE )) { // ... no other 1d hyp on anOppE
+// // Add found edge to the chain oriented so that to
+// // have it co-directed with a forward MainEdge
+// TopAbs_Orientation ori = anE.Orientation();
+// if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
+// ori = TopAbs::Reverse( ori );
+// anOppE.Orientation( ori );
+// aChain.Add(anOppE);
+// listCurEdges.Append(anOppE);
+// }
+// else {
+// // Collision!
+// MESSAGE("Error: Collision between propagated hypotheses");
+// CleanMeshOnPropagationChain(theMainEdge);
+// aChain.Clear();
+// return ( aMainHyp == isLocal1DHypothesis(aMainEdgeForOppEdge) );
+// }
+// }
+// }
+// } // if (nb == 5 && found > 0)
+// } // if (aF.ShapeType() == TopAbs_WIRE)
+// } // for (; itF.More(); itF.Next())
+// } // for (; itE.More(); itE.Next())
+
+// listPrevEdges = listCurEdges;
+// } // while (listPrevEdges.Extent() > 0)
+
+// CleanMeshOnPropagationChain(theMainEdge);
+ return true;
+ }
+ //================================================================================
+ /*!
+ * \brief Clear propagation chain
+ */
+ //================================================================================
+
+ bool clearPropagationChain( SMESH_subMesh* subMesh )
+ {
+ if ( PropagationMgrData* data = getData( subMesh )) {
+ if ( data->State() == IN_CHAIN )
+ return clearPropagationChain( data->GetSource() );
+ return true;
+ }
+ return false;
+ }
+
+
+ //================================================================================
+ /*!
+ * \brief Constructor
+ */
+ PropagationMgr::PropagationMgr()
+ : SMESH_subMeshEventListener( false ) // won't be deleted by submesh
+ {}
+ //================================================================================
+ /*!
+ * \brief Set PropagationMgr on a submesh
+ */
+ void PropagationMgr::Set(SMESH_subMesh * submesh)
+ {
+ EventListenerData* data = EventListenerData::MakeData(submesh,WAIT_PROPAG_HYP);
+
+ submesh->SetEventListener( getListener(), data, submesh );
+
+ const SMESH_Hypothesis * propagHyp =
+ submesh->GetFather()->GetHypothesis( submesh->GetSubShape(), propagHypFilter(), true );
+ if ( propagHyp )
+ getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP,
+ SMESH_subMesh::ALGO_EVENT,
+ submesh,
+ data,
+ propagHyp);
+ }
+
+ //================================================================================
+ /*!
+ * \brief React on events on 1D submeshes
+ */
+ //================================================================================
+
+ void PropagationMgr::ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ SMESH_subMeshEventListenerData* data,
+ const SMESH_Hypothesis* hyp)
+ {
+ if ( !data )
+ return;
+ if ( !hyp || hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO || hyp->GetDim() != 1 )
+ return;
+ if ( eventType != SMESH_subMesh::ALGO_EVENT )
+ return;
+
+ bool isPropagHyp = ( StdMeshers_Propagation::GetName() != hyp->GetName() );
+
+ switch ( data->myType ) {
+
+ case WAIT_PROPAG_HYP: { // no propagation hyp in chain
+ // --------------------------------------------------------
+ if ( !isPropagHyp )
+ return;
+ if ( !isLocal1DHypothesis( *subMesh->GetFather(), subMesh->GetSubShape()))
+ return;
+ if ( event == SMESH_subMesh::ADD_HYP ||
+ event == SMESH_subMesh::ADD_FATHER_HYP ) // add propagation hyp
+ {
+ // build propagation chain
+ clearPropagationChain( subMesh );
+ buildPropagationChain( subMesh );
+ }
+ return;
+ }
+ case HAS_PROPAG_HYP: { // propag hyp on this submesh
+ // --------------------------------------------------------
+ switch ( event ) {
+ case SMESH_subMesh::REMOVE_HYP:
+ case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
+ if ( isPropagHyp )
+ {
+ // clear propagation chain
+ }
+ return;
+ case SMESH_subMesh::MODIF_HYP: // hyp modif
+ // clear mesh in a chain
+ return;
+ }
+ return;
+ }
+ case IN_CHAIN: { // submesh is in propagation chain
+ // --------------------------------------------------------
+ if ( event == SMESH_subMesh::ADD_HYP ) // add local hypothesis
+ if ( isPropagHyp )
+ ; // collision
+ else
+ ; // rebuild propagation chain
+ return;
+ }
+ case LAST_IN_CHAIN: { // submesh with local 1D hyp, breaking a chain
+ // --------------------------------------------------------
+ if ( event == SMESH_subMesh::REMOVE_HYP ) // remove local hyp
+ ; // rebuild propagation chain
+ return;
+ }
+ } // switch by SubMeshState
+ }
+} // namespace
#include "SMESH_StdMeshers.hxx"
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMeshEventListener.hxx"
#include "Utils_SALOME_Exception.hxx"
+#include <TopoDS_Edge.hxx>
+
+
+// =======================================================================
+/*!
+ * \brief Propagation hypothesis
+ */
+// =======================================================================
+
class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
{
public:
static std::string GetName ();
+ /*!
+ * \brief Set EventListener managing propagation of hypotheses
+ * \param subMesh - edge submesh to set event listener on
+ *
+ * 1D algo is expected to call this method from it's SetEventListener()
+ */
+ static void SetPropagationMgr(SMESH_subMesh* subMesh);
+
+ /*!
+ * \brief Return an edge from which hypotheses are propagated from
+ * \param theMesh - mesh
+ * \param theEdge - edge to which hypotheses are propagated
+ * \retval TopoDS_Edge - source edge, also passing orientation
+ */
+ static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge);
+
/*!
* \brief Initialize my parameter values by the mesh built on the geometry
* \param theMesh - the built mesh
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
};
-
#endif
// $Header$
#include "StdMeshers_Quadrangle_2D.hxx"
+
+#include "StdMeshers_FaceSide.hxx"
+
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
+#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
+#include <BRepLProp.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
-
#include <Geom_Surface.hxx>
#include <Geom_Curve.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <TopExp.hxx>
-
#include <Precision.hxx>
#include <gp_Pnt2d.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColgp_SequenceOfXY.hxx>
+#include <NCollection_DefineArray2.hxx>
#include "utilities.h"
#include "Utils_ExceptHandlers.hxx"
#ifndef StdMeshers_Array2OfNode_HeaderFile
#define StdMeshers_Array2OfNode_HeaderFile
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-#include <NCollection_DefineArray2.hxx>
DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
DEFINE_ARRAY2(StdMeshers_Array2OfNode,
StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
using namespace std;
+typedef gp_XY gp_UV;
+typedef SMESH_Comment TComm;
+
//=============================================================================
/*!
*
StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D()
{
MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D");
- if ( myTool )
- delete myTool;
}
//=============================================================================
const TopoDS_Shape& aShape) throw (SALOME_Exception)
{
Unexpect aCatch(SalomeException);
- //MESSAGE("StdMeshers_Quadrangle_2D::Compute");
+
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
aMesh.GetSubMesh(aShape);
- if ( !myTool )
- myTool = new SMESH_MesherHelper(aMesh);
- _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+ SMESH_MesherHelper helper(aMesh);
+ myTool = &helper;
- //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape);
- FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape);
+ _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
- if (!quad) {
- delete myTool; myTool = 0;
+ FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape );
+ std::auto_ptr<FaceQuadStruct> quadDeleter( quad ); // to delete quad at exit from Compute()
+ if (!quad)
return false;
- }
if(myQuadranglePreference) {
- int n1 = quad->nbPts[0];
- int n2 = quad->nbPts[1];
- int n3 = quad->nbPts[2];
- int n4 = quad->nbPts[3];
+ int n1 = quad->side[0]->NbPoints();
+ int n2 = quad->side[1]->NbPoints();
+ int n3 = quad->side[2]->NbPoints();
+ int n4 = quad->side[3]->NbPoints();
int nfull = n1+n2+n3+n4;
int ntmp = nfull/2;
ntmp = ntmp*2;
if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
// special path for using only quandrangle faces
bool ok = ComputeQuadPref(aMesh, aShape, quad);
- delete myTool; myTool = 0;
return ok;
}
}
// set normalized grid on unit square in parametric domain
- SetNormalizedGrid(aMesh, aShape, quad);
- if (!quad) {
- delete myTool; myTool = 0;
+
+ if (!SetNormalizedGrid(aMesh, aShape, quad))
return false;
- }
// --- compute 3D values on points, store points & quadrangles
- int nbdown = quad->nbPts[0];
- int nbup = quad->nbPts[2];
+ int nbdown = quad->side[0]->NbPoints();
+ int nbup = quad->side[2]->NbPoints();
- int nbright = quad->nbPts[1];
- int nbleft = quad->nbPts[3];
+ int nbright = quad->side[1]->NbPoints();
+ int nbleft = quad->side[3]->NbPoints();
int nbhoriz = Min(nbdown, nbup);
int nbvertic = Min(nbright, nbleft);
b = quad->uv_grid[j * nbhoriz + i + 1].node;
c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
- //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
-
- UVPtStruct *uv_e0 = quad->uv_edges[0];
- UVPtStruct *uv_e1 = quad->uv_edges[1];
- UVPtStruct *uv_e2 = quad->uv_edges[2];
- UVPtStruct *uv_e3 = quad->uv_edges[3];
+
+ const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_e1 = quad->side[1]->GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_e3 = quad->side[3]->GetUVPtStruct(false,0);
double eps = Precision::Confusion();
}
}
- QuadDelete(quad);
- delete myTool; myTool = 0;
-
bool isOk = true;
return isOk;
}
-
//=============================================================================
/*!
*
*/
//=============================================================================
-FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
+FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape)
throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
const TopoDS_Face & F = TopoDS::Face(aShape);
+ const bool ignoreMediumNodes = _quadraticMesh;
// verify 1 wire only, with 4 edges
-
- if (NumberOfWires(F) != 1) {
- INFOS("only 1 wire by face (quadrangles)");
+ TopoDS_Vertex V;
+ list< TopoDS_Edge > edges;
+ list< int > nbEdgesInWire;
+ int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+ if (nbWire != 1) {
+ error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire);
return 0;
}
- const TopoDS_Wire& W = BRepTools::OuterWire(F);
- BRepTools_WireExplorer wexp (W, F);
-
FaceQuadStruct* quad = new FaceQuadStruct;
- for (int i = 0; i < 4; i++)
- quad->uv_edges[i] = 0;
quad->uv_grid = 0;
-
- int nbEdges = 0;
- for (wexp.Init(W, F); wexp.More(); wexp.Next()) {
- const TopoDS_Edge& E = wexp.Current();
- int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- if (nbEdges < 4) {
- quad->edge[nbEdges] = E;
- if(!_quadraticMesh) {
- quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+ quad->side.reserve(nbEdgesInWire.front());
+
+ int nbSides = 0;
+ list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+ if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
+ for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ )
+ quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
+ nbSides<TOP_SIDE, ignoreMediumNodes));
+ }
+ else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ list< TopoDS_Edge > sideEdges;
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+ bool sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.back(), edges.front() );
+ sameSide = ( cont >= GeomAbs_G1 );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
}
- else {
- int tmp = nb/2;
- quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema
+ if ( nbSides == 0 ) { // go backward from the first edge
+ sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.front(), edges.back() );
+ sameSide = ( cont >= GeomAbs_G1 );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
}
+ quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+ nbSides<TOP_SIDE, ignoreMediumNodes));
+ ++nbSides;
}
- nbEdges++;
}
-
- if (nbEdges != 4) {
- INFOS("face must have 4 edges /quadrangles");
- QuadDelete(quad);
- return 0;
+ if (nbSides != 4) {
+#ifdef _DEBUG_
+ cout << endl << "StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:";
+ for ( int i = 0; i < nbSides; ++i ) {
+ cout << " ( ";
+ for ( int e = 0; e < quad->side[i]->NbEdges(); ++e )
+ cout << myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " ";
+ cout << ")";
+ }
+ cout << endl;
+#endif
+ error(COMPERR_BAD_SHAPE, TComm("Face must have 4 side but not ") << nbSides);
+ delete quad;
+ quad = 0;
}
return quad;
//=============================================================================
FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
- (SMESH_Mesh & aMesh,
+ (SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
- const bool CreateQuadratic) throw(SALOME_Exception)
+ const bool CreateQuadratic) throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
*/
//=============================================================================
-void StdMeshers_Quadrangle_2D::QuadDelete (FaceQuadStruct * quad)
+faceQuadStruct::~faceQuadStruct()
{
- //MESSAGE("StdMeshers_Quadrangle_2D::QuadDelete");
- if (quad)
+ for (int i = 0; i < side.size(); i++) {
+ if (side[i]) delete side[i];
+ }
+ if (uv_grid) delete [] uv_grid;
+}
+
+namespace {
+ inline const vector<UVPtStruct>& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg)
{
- for (int i = 0; i < 4; i++)
- {
- if (quad->uv_edges[i])
- delete [] quad->uv_edges[i];
- quad->edge[i].Nullify();
- }
- if (quad->uv_grid)
- delete [] quad->uv_grid;
- delete quad;
+ bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE );
+ double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1;
+ return
+ quad->isEdgeOut[i] ?
+ quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) :
+ quad->side[i]->GetUVPtStruct(isXConst,constValue);
}
}
*/
//=============================================================================
-void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
+bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
const TopoDS_Shape& aShape,
FaceQuadStruct* & quad) throw (SALOME_Exception)
{
// transport - projection sur le carré unité
// MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid");
- const TopoDS_Face& F = TopoDS::Face(aShape);
+// const TopoDS_Face& F = TopoDS::Face(aShape);
// 1 --- find orientation of the 4 edges, by test on extrema
// =down
//
- Handle(Geom2d_Curve) c2d[4];
- gp_Pnt2d pf[4];
- gp_Pnt2d pl[4];
- for (int i = 0; i < 4; i++)
- {
- c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], F,
- quad->first[i], quad->last[i]);
- pf[i] = c2d[i]->Value(quad->first[i]);
- pl[i] = c2d[i]->Value(quad->last[i]);
- quad->isEdgeForward[i] = false;
- }
-
- double l0f1 = pl[0].SquareDistance(pf[1]);
- double l0l1 = pl[0].SquareDistance(pl[1]);
- double f0f1 = pf[0].SquareDistance(pf[1]);
- double f0l1 = pf[0].SquareDistance(pl[1]);
- if ( Min( l0f1, l0l1 ) < Min ( f0f1, f0l1 ))
- {
- quad->isEdgeForward[0] = true;
- } else {
- double tmp = quad->first[0];
- quad->first[0] = quad->last[0];
- quad->last[0] = tmp;
- pf[0] = c2d[0]->Value(quad->first[0]);
- pl[0] = c2d[0]->Value(quad->last[0]);
- }
- for (int i = 1; i < 4; i++)
- {
- l0l1 = pl[i - 1].SquareDistance(pl[i]);
- l0f1 = pl[i - 1].SquareDistance(pf[i]);
- quad->isEdgeForward[i] = ( l0f1 < l0l1 );
- if (!quad->isEdgeForward[i])
- {
- double tmp = quad->first[i];
- quad->first[i] = quad->last[i];
- quad->last[i] = tmp;
- pf[i] = c2d[i]->Value(quad->first[i]);
- pl[i] = c2d[i]->Value(quad->last[i]);
- }
- }
-
- // 2 --- load 2d edge points (u,v) with orientation and value on unit square
-
- bool loadOk = true;
- for (int i = 0; i < 2; i++)
- {
- quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
- quad->first[i], quad->last[i]);
- if (!quad->uv_edges[i]) loadOk = false;
- }
-
- for (int i = 2; i < 4; i++)
- {
- quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
- quad->last[i], quad->first[i]);
- if (!quad->uv_edges[i]) loadOk = false;
- }
-
- if (!loadOk)
- {
- INFOS("StdMeshers_Quadrangle_2D::SetNormalizedGrid - LoadEdgePoints failed");
- QuadDelete( quad );
- quad = 0;
- return;
- }
// 3 --- 2D normalized values on unit square [0..1][0..1]
- int nbhoriz = Min(quad->nbPts[0], quad->nbPts[2]);
- int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
+ int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
+ int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
- quad->isEdgeOut[0] = (quad->nbPts[0] > quad->nbPts[2]);
- quad->isEdgeOut[1] = (quad->nbPts[1] > quad->nbPts[3]);
- quad->isEdgeOut[2] = (quad->nbPts[2] > quad->nbPts[0]);
- quad->isEdgeOut[3] = (quad->nbPts[3] > quad->nbPts[1]);
+ quad->isEdgeOut[0] = (quad->side[0]->NbPoints() > quad->side[2]->NbPoints());
+ quad->isEdgeOut[1] = (quad->side[1]->NbPoints() > quad->side[3]->NbPoints());
+ quad->isEdgeOut[2] = (quad->side[2]->NbPoints() > quad->side[0]->NbPoints());
+ quad->isEdgeOut[3] = (quad->side[3]->NbPoints() > quad->side[1]->NbPoints());
- quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
+ UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
- UVPtStruct *uv_grid = quad->uv_grid;
- UVPtStruct *uv_e0 = quad->uv_edges[0];
- UVPtStruct *uv_e1 = quad->uv_edges[1];
- UVPtStruct *uv_e2 = quad->uv_edges[2];
- UVPtStruct *uv_e3 = quad->uv_edges[3];
+ const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 );
+ const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 );
+ const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
+ const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 );
+
+ if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
+ return error(dfltErr(), "Can't find nodes on sides");
// nodes Id on "in" edges
if (! quad->isEdgeOut[0]) {
}
}
- // falsificate "out" edges
- if (quad->isEdgeOut[0]) // down
- uv_e0 = MakeEdgePoints
- (aMesh, F, quad->edge[0], quad->first[0], quad->last[0], nbhoriz - 1);
- else if (quad->isEdgeOut[2]) // up
- uv_e2 = MakeEdgePoints
- (aMesh, F, quad->edge[2], quad->last[2], quad->first[2], nbhoriz - 1);
-
- if (quad->isEdgeOut[1]) // right
- uv_e1 = MakeEdgePoints
- (aMesh, F, quad->edge[1], quad->first[1], quad->last[1], nbvertic - 1);
- else if (quad->isEdgeOut[3]) // left
- uv_e3 = MakeEdgePoints
- (aMesh, F, quad->edge[3], quad->last[3], quad->first[3], nbvertic - 1);
-
// normalized 2d values on grid
for (int i = 0; i < nbhoriz; i++)
{
}
// 4 --- projection on 2d domain (u,v)
- gp_Pnt2d a0 = pf[0];
- gp_Pnt2d a1 = pf[1];
- gp_Pnt2d a2 = pf[2];
- gp_Pnt2d a3 = pf[3];
+ gp_UV a0( uv_e0.front().u, uv_e0.front().v );
+ gp_UV a1( uv_e0.back().u, uv_e0.back().v );
+ gp_UV a2( uv_e2.back().u, uv_e2.back().v );
+ gp_UV a3( uv_e2.front().u, uv_e2.front().v );
for (int i = 0; i < nbhoriz; i++)
{
int ij = j * nbhoriz + i;
double x = uv_grid[ij].x;
double y = uv_grid[ij].y;
- double param_0 = uv_e0[0].param + x * (uv_e0[nbhoriz - 1].param - uv_e0[0].param); // sud
- double param_2 = uv_e2[0].param + x * (uv_e2[nbhoriz - 1].param - uv_e2[0].param); // nord
- double param_1 = uv_e1[0].param + y * (uv_e1[nbvertic - 1].param - uv_e1[0].param); // est
- double param_3 = uv_e3[0].param + y * (uv_e3[nbvertic - 1].param - uv_e3[0].param); // ouest
+ double param_0 = uv_e0[0].normParam + x * (uv_e0.back().normParam - uv_e0[0].normParam); // sud
+ double param_2 = uv_e2[0].normParam + x * (uv_e2.back().normParam - uv_e2[0].normParam); // nord
+ double param_1 = uv_e1[0].normParam + y * (uv_e1.back().normParam - uv_e1[0].normParam); // est
+ double param_3 = uv_e3[0].normParam + y * (uv_e3.back().normParam - uv_e3[0].normParam); // ouest
//MESSAGE("params "<<param_0<<" "<<param_1<<" "<<param_2<<" "<<param_3);
- gp_Pnt2d p0 = c2d[0]->Value(param_0);
- gp_Pnt2d p1 = c2d[1]->Value(param_1);
- gp_Pnt2d p2 = c2d[2]->Value(param_2);
- gp_Pnt2d p3 = c2d[3]->Value(param_3);
+ gp_UV p0 = quad->side[0]->Value2d(param_0).XY();
+ gp_UV p1 = quad->side[1]->Value2d(param_1).XY();
+ gp_UV p2 = quad->side[2]->Value2d(param_2).XY();
+ gp_UV p3 = quad->side[3]->Value2d(param_3).XY();
- double u = (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X();
- double v = (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y();
+ gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3;
+ uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
- u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() +
- x * y * a2.X() + (1 - x) * y * a3.X();
- v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() +
- x * y * a2.Y() + (1 - x) * y * a3.Y();
-
- uv_grid[ij].u = u;
- uv_grid[ij].v = v;
+ uv_grid[ij].u = uv.X();
+ uv_grid[ij].v = uv.Y();
}
}
+ return true;
}
-
//=======================================================================
//function : ShiftQuad
//purpose : auxilary function for ComputeQuadPref
//=======================================================================
-static void ShiftQuad(FaceQuadStruct* quad, const int num, bool WisF)
+
+static void ShiftQuad(FaceQuadStruct* quad, const int num, bool)
{
- if(num>3) return;
- int i;
- for(i=1; i<=num; i++) {
- int nbPts3 = quad->nbPts[0];
- quad->nbPts[0] = quad->nbPts[1];
- quad->nbPts[1] = quad->nbPts[2];
- quad->nbPts[2] = quad->nbPts[3];
- quad->nbPts[3] = nbPts3;
- TopoDS_Edge edge3 = quad->edge[0];
- quad->edge[0] = quad->edge[1];
- quad->edge[1] = quad->edge[2];
- quad->edge[2] = quad->edge[3];
- quad->edge[3] = edge3;
- double first3 = quad->first[0];
- quad->first[0] = quad->first[1];
- quad->first[1] = quad->first[2];
- quad->first[2] = quad->first[3];
- quad->first[3] = first3;
- double last3 = quad->last[0];
- quad->last[0] = quad->last[1];
- quad->last[1] = quad->last[2];
- quad->last[2] = quad->last[3];
- quad->last[3] = last3;
- bool isEdgeForward3 = quad->isEdgeForward[0];
- quad->isEdgeForward[0] = quad->isEdgeForward[1];
- quad->isEdgeForward[1] = quad->isEdgeForward[2];
- quad->isEdgeForward[2] = quad->isEdgeForward[3];
- quad->isEdgeForward[3] = isEdgeForward3;
- bool isEdgeOut3 = quad->isEdgeOut[0];
- quad->isEdgeOut[0] = quad->isEdgeOut[1];
- quad->isEdgeOut[1] = quad->isEdgeOut[2];
- quad->isEdgeOut[2] = quad->isEdgeOut[3];
- quad->isEdgeOut[3] = isEdgeOut3;
- UVPtStruct* uv_edges3 = quad->uv_edges[0];
- quad->uv_edges[0] = quad->uv_edges[1];
- quad->uv_edges[1] = quad->uv_edges[2];
- quad->uv_edges[2] = quad->uv_edges[3];
- quad->uv_edges[3] = uv_edges3;
- }
- if(!WisF) {
- // replacement left and right edges
- int nbPts3 = quad->nbPts[1];
- quad->nbPts[1] = quad->nbPts[3];
- quad->nbPts[3] = nbPts3;
- TopoDS_Edge edge3 = quad->edge[1];
- quad->edge[1] = quad->edge[3];
- quad->edge[3] = edge3;
- double first3 = quad->first[1];
- quad->first[1] = quad->first[3];
- quad->first[3] = first3;
- double last3 = quad->last[1];
- quad->last[1] = quad->last[2];
- quad->last[3] = last3;
- bool isEdgeForward3 = quad->isEdgeForward[1];
- quad->isEdgeForward[1] = quad->isEdgeForward[3];
- quad->isEdgeForward[3] = isEdgeForward3;
- bool isEdgeOut3 = quad->isEdgeOut[1];
- quad->isEdgeOut[1] = quad->isEdgeOut[3];
- quad->isEdgeOut[3] = isEdgeOut3;
- UVPtStruct* uv_edges3 = quad->uv_edges[1];
- quad->uv_edges[1] = quad->uv_edges[3];
- quad->uv_edges[3] = uv_edges3;
+ StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] };
+ for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) {
+ int id = ( i + num ) % NB_SIDES;
+ bool wasForward = ( i < TOP_SIDE );
+ bool newForward = ( id < TOP_SIDE );
+ if ( wasForward != newForward )
+ side[ i ]->Reverse();
+ quad->side[ id ] = side[ i ];
}
}
-
//=======================================================================
//function : CalcUV
//purpose : auxilary function for ComputeQuadPref
//=======================================================================
-static gp_XY CalcUV(double x0, double x1, double y0, double y1,
+
+static gp_UV CalcUV(double x0, double x1, double y0, double y1,
FaceQuadStruct* quad,
- const gp_Pnt2d& a0, const gp_Pnt2d& a1,
- const gp_Pnt2d& a2, const gp_Pnt2d& a3,
- const Handle(Geom2d_Curve)& c2db,
- const Handle(Geom2d_Curve)& c2dr,
- const Handle(Geom2d_Curve)& c2dt,
- const Handle(Geom2d_Curve)& c2dl)
+ const gp_UV& a0, const gp_UV& a1,
+ const gp_UV& a2, const gp_UV& a3)
{
- int nb = quad->nbPts[0];
- int nr = quad->nbPts[1];
- int nt = quad->nbPts[2];
- int nl = quad->nbPts[3];
-
- UVPtStruct* uv_eb = quad->uv_edges[0];
- UVPtStruct* uv_er = quad->uv_edges[1];
- UVPtStruct* uv_et = quad->uv_edges[2];
- UVPtStruct* uv_el = quad->uv_edges[3];
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
double y = y0 + x * (y1 - y0);
- double param_b = uv_eb[0].param + x * (uv_eb[nb-1].param - uv_eb[0].param);
- double param_t = uv_et[0].param + x * (uv_et[nt-1].param - uv_et[0].param);
- double param_r = uv_er[0].param + y * (uv_er[nr-1].param - uv_er[0].param);
- double param_l = uv_el[0].param + y * (uv_el[nl-1].param - uv_el[0].param);
-
- gp_Pnt2d p0 = c2db->Value(param_b);
- gp_Pnt2d p1 = c2dr->Value(param_r);
- gp_Pnt2d p2 = c2dt->Value(param_t);
- gp_Pnt2d p3 = c2dl->Value(param_l);
+ double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam);
+ double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam);
+ double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam);
+ double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam);
- double u = (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X();
- double v = (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y();
+ gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY();
+ gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY();
+ gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY();
+ gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY();
- u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() +
- x * y * a2.X() + (1 - x) * y * a3.X();
- v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() +
- x * y * a2.Y() + (1 - x) * y * a3.Y();
+ gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
- //cout<<"x0="<<x0<<" x1="<<x1<<" y0="<<y0<<" y1="<<y1<<endl;
- //cout<<"x="<<x<<" y="<<y<<endl;
- //cout<<"param_b="<<param_b<<" param_t="<<param_t<<" param_r="<<param_r<<" param_l="<<param_l<<endl;
- //cout<<"u="<<u<<" v="<<v<<endl;
+ uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
- return gp_XY(u,v);
+ return uv;
}
-
-//=======================================================================
-//function : ComputeQuadPref
-//purpose :
//=======================================================================
/*!
- * Special function for creation only quandrangle faces
+ * Create only quandrangle faces
*/
-bool StdMeshers_Quadrangle_2D::ComputeQuadPref
- (SMESH_Mesh & aMesh,
- const TopoDS_Shape& aShape,
- FaceQuadStruct* quad) throw (SALOME_Exception)
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh,
+ const TopoDS_Shape& aShape,
+ FaceQuadStruct* quad)
+ throw (SALOME_Exception)
{
Unexpect aCatch(SalomeException);
if(!FisF) WisF = !WisF;
int i,j,geomFaceID = meshDS->ShapeToIndex( F );
- int nb = quad->nbPts[0];
- int nr = quad->nbPts[1];
- int nt = quad->nbPts[2];
- int nl = quad->nbPts[3];
+ int nb = quad->side[0]->NbPoints();
+ int nr = quad->side[1]->NbPoints();
+ int nt = quad->side[2]->NbPoints();
+ int nl = quad->side[3]->NbPoints();
int dh = abs(nb-nt);
int dv = abs(nr-nl);
}
else {
if( nr>nl ) {
- // we have to shift quad on 3
- ShiftQuad(quad,3,WisF);
- }
- else {
// we have to shift quad on 1
ShiftQuad(quad,1,WisF);
}
+ else {
+ // we have to shift quad on 3
+ ShiftQuad(quad,3,WisF);
+ }
}
- nb = quad->nbPts[0];
- nr = quad->nbPts[1];
- nt = quad->nbPts[2];
- nl = quad->nbPts[3];
+ nb = quad->side[0]->NbPoints();
+ nr = quad->side[1]->NbPoints();
+ nt = quad->side[2]->NbPoints();
+ nl = quad->side[3]->NbPoints();
dh = abs(nb-nt);
dv = abs(nr-nl);
int nbh = Max(nb,nt);
nbh = nbh + addh;
}
- Handle(Geom2d_Curve) c2d[4];
- for(i=0; i<4; i++) {
- c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], F,
- quad->first[i], quad->last[i]);
- }
-
- bool loadOk = true;
- for(i=0; i<2; i++) {
- quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], false);
- if(!quad->uv_edges[i]) loadOk = false;
- }
- for(i=2; i<4; i++) {
- quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], true);
- if (!quad->uv_edges[i]) loadOk = false;
- }
- if (!loadOk) {
- INFOS("StdMeshers_Quadrangle_2D::ComputeQuadPref - LoadEdgePoints failed");
- QuadDelete( quad );
- quad = 0;
- return false;
- }
-
- UVPtStruct* uv_eb = quad->uv_edges[0];
- UVPtStruct* uv_er = quad->uv_edges[1];
- UVPtStruct* uv_et = quad->uv_edges[2];
- UVPtStruct* uv_el = quad->uv_edges[3];
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
// arrays for normalized params
//cout<<"Dump B:"<<endl;
TColStd_SequenceOfReal npb, npr, npt, npl;
for(i=0; i<nb; i++) {
npb.Append(uv_eb[i].normParam);
- //cout<<"i="<<i<<" par="<<uv_eb[i].param<<" npar="<<uv_eb[i].normParam;
+ //cout<<"i="<<i<<" par="<<uv_eb[i].normParam<<" npar="<<uv_eb[i].normParam;
//const SMDS_MeshNode* N = uv_eb[i].node;
//cout<<" node("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
}
npl.Append(uv_el[i].normParam);
}
- // we have to add few values of params to right and left
- // insert them after first param
+ // add some params to right and left after the first param
// insert to right
int dr = nbv - nr;
double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
//}
//cout<<endl;
- gp_Pnt2d a[4];
- c2d[0]->D0(uv_eb[0].param,a[0]);
- c2d[0]->D0(uv_eb[nb-1].param,a[1]);
- c2d[2]->D0(uv_et[nt-1].param,a[2]);
- c2d[2]->D0(uv_et[0].param,a[3]);
- //cout<<" a[0]("<<a[0].X()<<","<<a[0].Y()<<")"<<" a[1]("<<a[1].X()<<","<<a[1].Y()<<")"
- // <<" a[2]("<<a[2].X()<<","<<a[2].Y()<<")"<<" a[3]("<<a[3].X()<<","<<a[3].Y()<<")"<<endl;
+ gp_XY a0( uv_eb.front().u, uv_eb.front().v );
+ gp_XY a1( uv_eb.back().u, uv_eb.back().v );
+ gp_XY a2( uv_et.back().u, uv_et.back().v );
+ gp_XY a3( uv_et.front().u, uv_et.front().v );
+ //cout<<" a0("<<a0.X()<<","<<a0.Y()<<")"<<" a1("<<a1.X()<<","<<a1.Y()<<")"
+ // <<" a2("<<a2.X()<<","<<a2.Y()<<")"<<" a3("<<a3.X()<<","<<a3.Y()<<")"<<endl;
int nnn = Min(nr,nl);
// auxilary sequence of XY for creation nodes
// step1: create faces for left domain
StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
// add left nodes
- for(j=1; j<=nl; j++)
+ for(j=1; j<=nl; j++)
NodesL.SetValue(1,j,uv_el[j-1].node);
if(dl>0) {
// add top nodes
// diagonal node
double y0 = npl.Value(i+1);
double y1 = npr.Value(i+1);
- gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
- c2d[0], c2d[1], c2d[2], c2d[3]);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
for(j=2; j<nl; j++) {
double y0 = npl.Value(dl+j);
double y1 = npr.Value(dl+j);
- gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
- c2d[0], c2d[1], c2d[2], c2d[3]);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
else {
// fill UVL using c2d
for(i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
- gp_Pnt2d p2d;
- c2d[3]->D0(uv_el[i].param,p2d);
- UVL.Append(p2d.XY());
+ UVL.Append( gp_UV ( uv_el[i].u, uv_el[i].v ));
}
}
// diagonal node
double y0 = npl.Value(i+1);
double y1 = npr.Value(i+1);
- gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
- c2d[0], c2d[1], c2d[2], c2d[3]);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
for(j=2; j<nr; j++) {
double y0 = npl.Value(nbv-j+1);
double y1 = npr.Value(nbv-j+1);
- gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
- c2d[0], c2d[1], c2d[2], c2d[3]);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
else {
// fill UVR using c2d
for(i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
- gp_Pnt2d p2d;
- c2d[1]->D0(uv_er[i].param,p2d);
- UVR.Append(p2d.XY());
+ UVR.Append( gp_UV( uv_er[i].u, uv_er[i].v ));
}
}
for(i=dl+2; i<nbh-dr; i++)
NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
// add bottom nodes (first columns)
- for(i=2; i<nb; i++) {
+ for(i=2; i<nb; i++)
NodesC.SetValue(i,1,uv_eb[i-1].node);
- gp_Pnt2d p2d;
- c2d[0]->D0(uv_eb[i-1].param,p2d);
- }
+
// create and add needed nodes
// add linear layers
for(i=2; i<nb; i++) {
for(j=1; j<nnn; j++) {
double y0 = npl.Value(nbv-nnn+j);
double y1 = npr.Value(nbv-nnn+j);
- gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
- c2d[0], c2d[1], c2d[2], c2d[3]);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
}
}
- QuadDelete(quad);
bool isOk = true;
return isOk;
}
-
-//=============================================================================
-/*!
- * LoadEdgePoints2
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh,
- const TopoDS_Face& F,
- const TopoDS_Edge& E,
- bool IsReverse)
-{
- //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
- // --- IDNodes of first and last Vertex
- TopoDS_Vertex VFirst, VLast;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
-
- ASSERT(!VFirst.IsNull());
- SMDS_NodeIteratorPtr lid = aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
- if (!lid->more()) {
- MESSAGE ( "NO NODE BUILT ON VERTEX" );
- return 0;
- }
- const SMDS_MeshNode* idFirst = lid->next();
-
- ASSERT(!VLast.IsNull());
- lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
- if (!lid->more()) {
- MESSAGE ( "NO NODE BUILT ON VERTEX" );
- return 0;
- }
- const SMDS_MeshNode* idLast = lid->next();
-
- // --- edge internal IDNodes (relies on good order storage, not checked)
-
- map<double, const SMDS_MeshNode *> params;
- SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
- int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-
- if(!_quadraticMesh) {
- while(ite->more()) {
- const SMDS_MeshNode* node = ite->next();
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
- }
- }
- else {
- vector<const SMDS_MeshNode*> nodes(nbPoints+2);
- nodes[0] = idFirst;
- nodes[nbPoints+1] = idLast;
- nbPoints = nbPoints/2;
- int nn = 1;
- while(ite->more()) {
- const SMDS_MeshNode* node = ite->next();
- nodes[nn++] = node;
- // check if node is medium
- bool IsMedium = false;
- SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
- while (itn->more()) {
- const SMDS_MeshElement* elem = itn->next();
- if ( elem->GetType() != SMDSAbs_Edge )
- continue;
- if(elem->IsMediumNode(node)) {
- IsMedium = true;
- break;
- }
- }
- if(IsMedium)
- continue;
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
- }
- }
-
- if (nbPoints != params.size()) {
- MESSAGE( "BAD NODE ON EDGE POSITIONS" );
- return 0;
- }
- UVPtStruct* uvslf = new UVPtStruct[nbPoints + 2];
-
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-
- const TopoDS_Wire& W = BRepTools::OuterWire(F);
- bool FisF = (F.Orientation()==TopAbs_FORWARD);
- bool WisF = (W.Orientation()==TopAbs_FORWARD);
- bool isForward = (E.Orientation()==TopAbs_FORWARD);
- //if(isForward) cout<<"E is FORWARD"<<endl;
- //else cout<<"E is REVERSED"<<endl;
- if(!WisF) isForward = !isForward;
- if(!FisF) isForward = !isForward;
- //bool isForward = !(E.Orientation()==TopAbs_FORWARD);
- if(IsReverse) isForward = !isForward;
- double paramin = 0;
- double paramax = 0;
- if (isForward) {
- paramin = f;
- paramax = l;
- gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward
- uvslf[0].x = p.X();
- uvslf[0].y = p.Y();
- uvslf[0].param = f;
- uvslf[0].node = idFirst;
- //MESSAGE("__ f "<<f<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
- map < double, const SMDS_MeshNode* >::iterator itp = params.begin();
- for (int i = 1; i <= nbPoints; i++) { // nbPoints internal
- double param = (*itp).first;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].node = (*itp).second;
- //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
- itp++;
- }
- p = C2d->Value(l); // last point = Vertex Reversed
- uvslf[nbPoints + 1].x = p.X();
- uvslf[nbPoints + 1].y = p.Y();
- uvslf[nbPoints + 1].param = l;
- uvslf[nbPoints + 1].node = idLast;
- //MESSAGE("__ l "<<l<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
- }
- else {
- paramin = l;
- paramax = f;
- gp_Pnt2d p = C2d->Value(l); // first point = Vertex Reversed
- uvslf[0].x = p.X();
- uvslf[0].y = p.Y();
- uvslf[0].param = l;
- uvslf[0].node = idLast;
- //MESSAGE("__ l "<<l<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
- map < double, const SMDS_MeshNode* >::reverse_iterator itp = params.rbegin();
- for (int j = nbPoints; j >= 1; j--) { // nbPoints internal
- double param = (*itp).first;
- int i = nbPoints + 1 - j;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].node = (*itp).second;
- //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
- itp++;
- }
- p = C2d->Value(f); // last point = Vertex Forward
- uvslf[nbPoints + 1].x = p.X();
- uvslf[nbPoints + 1].y = p.Y();
- uvslf[nbPoints + 1].param = f;
- uvslf[nbPoints + 1].node = idFirst;
- //MESSAGE("__ f "<<f<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
- }
-
- ASSERT(paramin != paramax);
- for (int i = 0; i < nbPoints + 2; i++) {
- uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
- }
-
- return uvslf;
-}
-
-
-//=============================================================================
-/*!
- * LoadEdgePoints
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh,
- const TopoDS_Face& F,
- const TopoDS_Edge& E,
- double first, double last)
-// bool isForward)
-{
- //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
-
- // --- IDNodes of first and last Vertex
-
- TopoDS_Vertex VFirst, VLast;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
-
- ASSERT(!VFirst.IsNull());
- SMDS_NodeIteratorPtr lid = aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
- if (!lid->more())
- {
- MESSAGE ( "NO NODE BUILT ON VERTEX" );
- return 0;
- }
- const SMDS_MeshNode* idFirst = lid->next();
-
- ASSERT(!VLast.IsNull());
- lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
- if (!lid->more())
- {
- MESSAGE ( "NO NODE BUILT ON VERTEX" );
- return 0;
- }
- const SMDS_MeshNode* idLast = lid->next();
-
- // --- edge internal IDNodes (relies on good order storage, not checked)
-
-// if(_quadraticMesh) {
- // fill myNLinkNodeMap
-// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
-// while(iter->more()) {
-// const SMDS_MeshElement* elem = iter->next();
-// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-// const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-// const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-// const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
-// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
-// myNLinkNodeMap[link] = n3;
-// }
-// }
-
- map<double, const SMDS_MeshNode *> params;
- SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
- int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-
- if(!_quadraticMesh) {
- while(ite->more()) {
- const SMDS_MeshNode* node = ite->next();
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
- }
- }
- else {
- nbPoints = nbPoints/2;
- while(ite->more()) {
- const SMDS_MeshNode* node = ite->next();
- // check if node is medium
- bool IsMedium = false;
- SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
- while (itn->more()) {
- const SMDS_MeshElement* elem = itn->next();
- if ( elem->GetType() != SMDSAbs_Edge )
- continue;
- if(elem->IsMediumNode(node)) {
- IsMedium = true;
- break;
- }
- }
- if(IsMedium)
- continue;
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
- }
- }
-
- if (nbPoints != params.size()) {
- MESSAGE( "BAD NODE ON EDGE POSITIONS" );
- return 0;
- }
- UVPtStruct* uvslf = new UVPtStruct[nbPoints + 2];
-
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-
- bool isForward = (((l - f) * (last - first)) > 0);
- double paramin = 0;
- double paramax = 0;
- if (isForward)
- {
- paramin = f;
- paramax = l;
- gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward
- uvslf[0].x = p.X();
- uvslf[0].y = p.Y();
- uvslf[0].param = f;
- uvslf[0].node = idFirst;
- //MESSAGE("__ f "<<f<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
- map < double, const SMDS_MeshNode* >::iterator itp = params.begin();
- for (int i = 1; i <= nbPoints; i++) // nbPoints internal
- {
- double param = (*itp).first;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].node = (*itp).second;
- //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
- itp++;
- }
- p = C2d->Value(l); // last point = Vertex Reversed
- uvslf[nbPoints + 1].x = p.X();
- uvslf[nbPoints + 1].y = p.Y();
- uvslf[nbPoints + 1].param = l;
- uvslf[nbPoints + 1].node = idLast;
- //MESSAGE("__ l "<<l<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
- } else
- {
- paramin = l;
- paramax = f;
- gp_Pnt2d p = C2d->Value(l); // first point = Vertex Reversed
- uvslf[0].x = p.X();
- uvslf[0].y = p.Y();
- uvslf[0].param = l;
- uvslf[0].node = idLast;
- //MESSAGE("__ l "<<l<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
- map < double, const SMDS_MeshNode* >::reverse_iterator itp = params.rbegin();
-
- for (int j = nbPoints; j >= 1; j--) // nbPoints internal
- {
- double param = (*itp).first;
- int i = nbPoints + 1 - j;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].node = (*itp).second;
- //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
- itp++;
- }
- p = C2d->Value(f); // last point = Vertex Forward
- uvslf[nbPoints + 1].x = p.X();
- uvslf[nbPoints + 1].y = p.Y();
- uvslf[nbPoints + 1].param = f;
- uvslf[nbPoints + 1].node = idFirst;
- //MESSAGE("__ f "<<f<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
- }
-
- ASSERT(paramin != paramax);
- for (int i = 0; i < nbPoints + 2; i++)
- {
- uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
- }
-
- return uvslf;
-}
-
-//=============================================================================
-/*!
- * MakeEdgePoints
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::MakeEdgePoints (SMESH_Mesh & aMesh,
- const TopoDS_Face& F,
- const TopoDS_Edge& E,
- double first, double last,
- int nb_segm)
-{
-// MESSAGE("StdMeshers_Quadrangle_2D::MakeEdgePoints");
-
- UVPtStruct* uvslf = new UVPtStruct[nb_segm + 1];
- list<double> params;
-
- // --- edge internal points
- double fi, li;
- Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, fi, li);
- if (!Curve.IsNull()) {
- try {
- GeomAdaptor_Curve C3d (Curve);
- double length = EdgeLength(E);
- double eltSize = length / nb_segm;
- GCPnts_UniformAbscissa Discret (C3d, eltSize, fi, li);
- if (!Discret.IsDone()) return false;
- int NbPoints = Discret.NbPoints();
- for (int i = 1; i <= NbPoints; i++) {
- double param = Discret.Parameter(i);
- params.push_back(param);
- }
- }
- catch (Standard_Failure) {
- return 0;
- }
- }
- else
- {
- // Edge is a degenerated Edge
- BRep_Tool::Range(E, fi, li);
- double du = (li - fi) / nb_segm;
- for (int i = 1; i <= nb_segm + 1; i++)
- {
- double param = fi + (i - 1) * du;
- params.push_back(param);
- }
- }
-
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- ASSERT(f != l);
-
- bool isForward = (((l - f) * (last - first)) > 0);
- if (isForward) {
- list<double>::iterator itU = params.begin();
- for (int i = 0; i <= nb_segm; i++) // nbPoints internal
- {
- double param = *itU;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].normParam = (param - f) / (l - f);
- itU++;
- }
- } else {
- list<double>::reverse_iterator itU = params.rbegin();
- for (int j = nb_segm; j >= 0; j--) // nbPoints internal
- {
- double param = *itU;
- int i = nb_segm - j;
- gp_Pnt2d p = C2d->Value(param);
- uvslf[i].x = p.X();
- uvslf[i].y = p.Y();
- uvslf[i].param = param;
- uvslf[i].normParam = (param - l) / (f - l);
- itU++;
- }
- }
-
- return uvslf;
-}
-
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & StdMeshers_Quadrangle_2D::SaveTo(ostream & save)
-{
- return save;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & StdMeshers_Quadrangle_2D::LoadFrom(istream & load)
-{
- return load;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Quadrangle_2D & hyp)
-{
- return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_Quadrangle_2D & hyp)
-{
- return hyp.LoadFrom( load );
-}
#include "SMESH_StdMeshers.hxx"
#include "SMESH_2D_Algo.hxx"
-#include "SMESH_Mesh.hxx"
#include "Utils_SALOME_Exception.hxx"
-#include "gp_XY.hxx"
-
-#include "SMESH_MesherHelper.hxx"
+class SMESH_Mesh;
+class SMESH_MesherHelper;
+class StdMeshers_FaceSide;
+struct uvPtStruct;
//class SMDS_MeshNode;
-typedef struct uvPtStruct
-{
- double param;
- double normParam;
- double u; // original 2d parameter
- double v;
- double x; // 2d parameter, normalized [0,1]
- double y;
- const SMDS_MeshNode * node;
-} UVPtStruct;
+enum TSideID { BOTTOM_SIDE=0, RIGHT_SIDE, TOP_SIDE, LEFT_SIDE, NB_SIDES };
+typedef uvPtStruct UVPtStruct;
typedef struct faceQuadStruct
{
- int nbPts[4];
- TopoDS_Edge edge[4];
- double first[4];
- double last[4];
- bool isEdgeForward[4];
+ //int nbPts[4];
+ //TopoDS_Edge edge[4];
+ vector< StdMeshers_FaceSide*> side;
+ //double first[4];
+ //double last[4];
+ //bool isEdgeForward[4];
bool isEdgeOut[4]; // true, if an edge has more nodes, than the opposite
- UVPtStruct* uv_edges[4];
+ //UVPtStruct* uv_edges[4];
UVPtStruct* uv_grid;
+ ~faceQuadStruct();
} FaceQuadStruct;
-class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D:
- public SMESH_2D_Algo
+class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo
{
public:
StdMeshers_Quadrangle_2D(int hypId, int studyId, SMESH_Gen* gen);
const bool CreateQuadratic)
throw (SALOME_Exception);
- static void QuadDelete(FaceQuadStruct* quad);
-
- /**
- * Returns NLinkNodeMap from myTool
- */
- const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); }
-
- ostream & SaveTo(ostream & save);
- istream & LoadFrom(istream & load);
- friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp);
- friend istream & operator >> (istream & load, StdMeshers_Quadrangle_2D & hyp);
-
protected:
FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape)
throw (SALOME_Exception);
- void SetNormalizedGrid(SMESH_Mesh& aMesh,
+ bool SetNormalizedGrid(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
FaceQuadStruct*& quad)
throw (SALOME_Exception);
// is not the same in the case where the global number of nodes on edges is even
bool myQuadranglePreference;
- SMESH_MesherHelper* myTool; // toll for working with quadratic elements
+ SMESH_MesherHelper* myTool; // tool for working with quadratic elements
};
#endif
#include <TopoDS_Solid.hxx>
#include <TopoDS_Shell.hxx>
#include <BRepTools.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <gp.hxx>
if ( !outerShell.IsSame( It.Value() ))
innerShell = It.Value();
if ( nbShells != 2 )
- RETURN_BAD_RESULT("Must be 2 shells");
+ return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not")<<nbShells);
// ----------------------------------
// Associate subshapes of the shells
if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
innerShell, &aMesh,
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
// ------------------
// Make mesh
TopoDS_Face outFace = TopoDS::Face( exp.Current() );
TopoDS_Face inFace;
if ( !shape2ShapeMap.IsBound( outFace )) {
- RETURN_BAD_RESULT("Association not found for face " << meshDS->ShapeToIndex( outFace ));
+ return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" )
+ << meshDS->ShapeToIndex( outFace ));
} else {
inFace = TopoDS::Face( shape2ShapeMap( outFace ));
}
TNodeNodeMap nodeIn2OutMap;
if ( ! TAssocTool::FindMatchingNodesOnFaces( inFace, &aMesh, outFace, &aMesh,
shape2ShapeMap, nodeIn2OutMap ))
- RETURN_BAD_RESULT("Different mesh on corresponding out and in faces: "
- << meshDS->ShapeToIndex( outFace ) << " and "
- << meshDS->ShapeToIndex( inFace ));
+ return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+ << meshDS->ShapeToIndex( outFace ) << " and "
+ << meshDS->ShapeToIndex( inFace ) << " seems different" );
+
// Create volumes
SMDS_ElemIteratorPtr faceIt = meshDS->MeshElements( inFace )->GetElements();
SMESHDS_Mesh * meshDS = myHelper->GetMeshDS();
int shapeID = myHelper->GetSubShapeID();
- if ( myLayerPositions.empty() )
- computeLayerPositions( gpXYZ( inNode ), gpXYZ( outNode ));
-
+ if ( myLayerPositions.empty() ) {
+ gp_Pnt pIn = gpXYZ( inNode ), pOut = gpXYZ( outNode );
+ computeLayerPositions( pIn, pOut );
+ }
int nbSegments = myLayerPositions.size() + 1;
TNode2ColumnMap::iterator n_col =
//================================================================================
//================================================================================
-class TNodeDistributor: private StdMeshers_Regular_1D
+class TNodeDistributor: public StdMeshers_Regular_1D
{
list <const SMESHDS_Hypothesis *> myUsedHyps;
public:
const StdMeshers_LayerDistribution* hyp)
{
double len = pIn.Distance( pOut );
- if ( len <= DBL_MIN ) RETURN_BAD_RESULT("Bad points");
+ if ( len <= DBL_MIN ) return error(dfltErr(),"Too close points of inner and outer shells");
if ( !hyp || !hyp->GetLayerDistribution() )
- RETURN_BAD_RESULT("Bad StdMeshers_LayerDistribution hypothesis");
+ return error(dfltErr(), "Invalid LayerDistribution hypothesis");
myUsedHyps.clear();
myUsedHyps.push_back( hyp->GetLayerDistribution() );
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut );
-
SMESH_Hypothesis::Hypothesis_Status aStatus;
if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus ))
- RETURN_BAD_RESULT("StdMeshers_Regular_1D::CheckHypothesis() failed with status "<<aStatus);
+ return error(dfltErr(), "StdMeshers_Regular_1D::CheckHypothesis() failed"
+ "with LayerDistribution hypothesis");
+ BRepAdaptor_Curve C3D(edge);
+ double f = C3D.FirstParameter(), l = C3D.LastParameter();
list< double > params;
- if ( !StdMeshers_Regular_1D::computeInternalParameters( edge, params, false ))
- RETURN_BAD_RESULT("StdMeshers_Regular_1D::computeInternalParameters() failed");
+ if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false ))
+ return error(dfltErr(),"StdMeshers_Regular_1D failed to compute layers distribution");
positions.clear();
positions.reserve( params.size() );
*/
//================================================================================
-bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut)
+bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn,
+ const gp_Pnt& pOut)
{
if ( myNbLayerHypo )
{
}
if ( myDistributionHypo ) {
SMESH_Mesh * mesh = myHelper->GetMesh();
- return TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
- *mesh, myDistributionHypo );
+ if ( !TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
+ *mesh, myDistributionHypo ))
+ {
+ error( TNodeDistributor::GetDistributor(*mesh)->GetComputeError() );
+ return false;
+ }
}
- RETURN_BAD_RESULT("Bad hypothesis");
+ RETURN_BAD_RESULT("Bad hypothesis");
}
class StdMeshers_NumberOfLayers;
class StdMeshers_LayerDistribution;
class SMESH_MesherHelper;
+class gp_Pnt;
class STDMESHERS_EXPORT StdMeshers_RadialPrism_3D: public SMESH_3D_Algo
{
const SMDS_MeshNode* outNode,
const SMDS_MeshNode* inNode);
- bool computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut);
+ bool computeLayerPositions(const gp_Pnt& pIn,
+ const gp_Pnt& pOut);
const StdMeshers_NumberOfLayers* myNbLayerHypo;
#include "StdMeshers_StartEndLength.hxx"
#include "StdMeshers_Deflection1D.hxx"
#include "StdMeshers_AutomaticLength.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_HypoFilter.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
-#include "SMDS_EdgePosition.hxx"
#include "Utils_SALOME_Exception.hxx"
#include "utilities.h"
+#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <GeomAdaptor_Curve.hxx>
+#include <TopExp_Explorer.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <GCPnts_UniformDeflection.hxx>
#include <Precision.hxx>
-#include <Expr_GeneralExpression.hxx>
-#include <Expr_NamedUnknown.hxx>
-#include <Expr_Array1OfNamedUnknown.hxx>
-#include <ExprIntrp_GenExp.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <OSD.hxx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
#include <string>
-#include <math.h>
using namespace std;
return ( _hypType != NONE );
}
-//=======================================================================
-//function : compensateError
-//purpose : adjust theParams so that the last segment length == an
-//=======================================================================
-
-static void compensateError(double a1, double an,
- double U1, double Un,
- double length,
- GeomAdaptor_Curve& C3d,
- list<double> & theParams)
-{
- int i, nPar = theParams.size();
- if ( a1 + an < length && nPar > 1 )
- {
- list<double>::reverse_iterator itU = theParams.rbegin();
- double Ul = *itU++;
- // dist from the last point to the edge end <Un>, it should be equal <an>
- double Ln = GCPnts_AbscissaPoint::Length( C3d, Ul, Un );
- double dLn = an - Ln; // error of <an>
- if ( Abs( dLn ) <= Precision::Confusion() )
- return;
- double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
- double dUn = dLn * Abs( Un - U1 ) / length; // parametric error of <an>
- if ( dUn < 0.5 * dU ) { // last segment is a bit shorter than it should
- dUn = -dUn; // move the last parameter to the edge beginning
- }
- else { // last segment is much shorter than it should -> remove the last param and
- theParams.pop_back(); nPar--; // move the rest points toward the edge end
- Ln = GCPnts_AbscissaPoint::Length( C3d, theParams.back(), Un );
- dUn = ( an - Ln ) * Abs( Un - U1 ) / length;
- if ( dUn < 0.5 * dU )
- dUn = -dUn;
- }
- if ( U1 > Un )
- dUn = -dUn;
- double q = dUn / ( nPar - 1 );
- for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
- (*itU) += dUn;
- dUn -= q;
- }
- }
-}
-
static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
double length, bool theReverse,
int nbSeg, Function& func,
return true;
}
+
+//================================================================================
+/*!
+ * \brief adjust internal node parameters so that the last segment length == an
+ * \param a1 - the first segment length
+ * \param an - the last segment length
+ * \param U1 - the first edge parameter
+ * \param Un - the last edge parameter
+ * \param length - the edge length
+ * \param C3d - the edge curve
+ * \param theParams - internal node parameters to adjust
+ * \param adjustNeighbors2an - to adjust length of segments next to the last one
+ * and not to remove parameters
+ */
+//================================================================================
+
+static void compensateError(double a1, double an,
+ double U1, double Un,
+ double length,
+ Adaptor3d_Curve& C3d,
+ list<double> & theParams,
+ bool adjustNeighbors2an = false)
+{
+ int i, nPar = theParams.size();
+ if ( a1 + an < length && nPar > 1 )
+ {
+ bool reverse = ( U1 > Un );
+ GCPnts_AbscissaPoint Discret(C3d, reverse ? an : -an, Un);
+ if ( !Discret.IsDone() )
+ return;
+ double Utgt = Discret.Parameter(); // target value of the last parameter
+ list<double>::reverse_iterator itU = theParams.rbegin();
+ double Ul = *itU++; // real value of the last parameter
+ double dUn = Utgt - Ul; // parametric error of <an>
+ if ( Abs(dUn) <= Precision::Confusion() )
+ return;
+ double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
+ if ( adjustNeighbors2an || Abs(dUn) < 0.5 * dU ) { // last segment is a bit shorter than it should
+ // move the last parameter to the edge beginning
+ }
+ else { // last segment is much shorter than it should -> remove the last param and
+ theParams.pop_back(); nPar--; // move the rest points toward the edge end
+ dUn = Utgt - theParams.back();
+ }
+
+ double q = dUn / ( nPar - 1 );
+ if ( !adjustNeighbors2an ) {
+ for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
+ (*itU) += dUn;
+ dUn -= q;
+ }
+ }
+ else {
+ theParams.back() += dUn;
+ double sign = reverse ? -1 : 1;
+ double prevU = theParams.back();
+ itU = theParams.rbegin();
+ for ( ++itU, i = 2; i < nPar; ++itU, i++ ) {
+ double newU = *itU + dUn;
+ if ( newU*sign < prevU*sign ) {
+ prevU = *itU = newU;
+ dUn -= q;
+ }
+ else { // set U between prevU and next valid param
+ list<double>::reverse_iterator itU2 = itU;
+ ++itU2;
+ int nb = 2;
+ while ( (*itU2)*sign > prevU*sign ) {
+ ++itU2; ++nb;
+ }
+ dU = ( *itU2 - prevU ) / nb;
+ while ( itU != itU2 ) {
+ *itU += dU; ++itU;
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Class used to clean mesh on edges when 0D hyp modified.
+ * Common approach doesn't work when 0D algo is missing because the 0D hyp is
+ * considered as not participating in computation whereas it is used by 1D algo.
+ */
+//================================================================================
+
+// struct VertexEventListener : public SMESH_subMeshEventListener
+// {
+// VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+// {}
+// /*!
+// * \brief Clean mesh on edges
+// * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+// * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+// * \param subMesh - the submesh where the event occures
+// */
+// void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+// EventListenerData*, const SMESH_Hypothesis*)
+// {
+// if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
+// {
+// subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
+// }
+// }
+// }; // struct VertexEventListener
+
+//=============================================================================
+/*!
+ * \brief Sets event listener to vertex submeshes
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//=============================================================================
+
+void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+// static VertexEventListener listener;
+// SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+// while (smIt->more()) {
+// subMesh->SetEventListener( &listener, 0, smIt->next() );
+// }
+}
+
+//=============================================================================
+/*!
+ * \brief Do nothing
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Regular_1D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+}
+
+//=============================================================================
+/*!
+ * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex
+ */
+//=============================================================================
+
+const StdMeshers_SegmentLengthAroundVertex*
+StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh & theMesh,
+ const TopoDS_Vertex & theV)
+{
+ static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D"));
+ if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true ))
+ {
+ SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h ));
+ const list <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
+ if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
+ return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
+ }
+ return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Tune parameters to fit "SegmentLengthAroundVertex" hypothesis
+ * \param theC3d - wire curve
+ * \param theLength - curve length
+ * \param theParameters - internal nodes parameters to modify
+ * \param theVf - 1st vertex
+ * \param theVl - 2nd vertex
+ */
+//================================================================================
+
+void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh & theMesh,
+ Adaptor3d_Curve & theC3d,
+ double theLength,
+ std::list< double > & theParameters,
+ const TopoDS_Vertex & theVf,
+ const TopoDS_Vertex & theVl)
+{
+ double f = theC3d.FirstParameter(), l = theC3d.LastParameter();
+ int nPar = theParameters.size();
+ for ( int isEnd1 = 0; isEnd1 < 2; ++isEnd1 )
+ {
+ const TopoDS_Vertex & V = isEnd1 ? theVf : theVl;
+ const StdMeshers_SegmentLengthAroundVertex* hyp = getVertexHyp (theMesh, V );
+ if ( hyp ) {
+ double vertexLength = hyp->GetLength();
+ if ( vertexLength > theLength / 2.0 )
+ continue;
+ if ( isEnd1 ) { // to have a segment of interest at end of theParameters
+ theParameters.reverse();
+ std::swap( f, l );
+ }
+ if ( _hypType == NB_SEGMENTS )
+ {
+ compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+ }
+ else if ( nPar <= 3 )
+ {
+ if ( !isEnd1 )
+ vertexLength = -vertexLength;
+ GCPnts_AbscissaPoint Discret(theC3d, vertexLength, l);
+ if ( Discret.IsDone() ) {
+ if ( nPar == 0 )
+ theParameters.push_back( Discret.Parameter());
+ else {
+ double L = GCPnts_AbscissaPoint::Length( theC3d, theParameters.back(), l);
+ if ( vertexLength < L / 2.0 )
+ theParameters.push_back( Discret.Parameter());
+ else
+ compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+ }
+ }
+ }
+ else
+ {
+ // recompute params between the last segment and a middle one.
+ // find size of a middle segment
+ int nHalf = ( nPar-1 ) / 2;
+ list< double >::reverse_iterator itU = theParameters.rbegin();
+ std::advance( itU, nHalf );
+ double Um = *itU++;
+ double Lm = GCPnts_AbscissaPoint::Length( theC3d, Um, *itU);
+ double L = GCPnts_AbscissaPoint::Length( theC3d, *itU, l);
+ StdMeshers_Regular_1D algo( *this );
+ algo._hypType = BEG_END_LENGTH;
+ algo._value[ BEG_LENGTH_IND ] = Lm;
+ algo._value[ END_LENGTH_IND ] = vertexLength;
+ double from = *itU, to = l;
+ if ( isEnd1 ) {
+ std::swap( from, to );
+ std::swap( algo._value[ BEG_LENGTH_IND ], algo._value[ END_LENGTH_IND ]);
+ }
+ list<double> params;
+ if ( algo.computeInternalParameters( theC3d, L, from, to, params, false ))
+ {
+ if ( isEnd1 ) params.reverse();
+ while ( 1 + nHalf-- )
+ theParameters.pop_back();
+ theParameters.splice( theParameters.end(), params );
+ }
+ else
+ {
+ compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+ }
+ }
+ if ( isEnd1 )
+ theParameters.reverse();
+ }
+ }
+}
+
//=============================================================================
/*!
*
*/
//=============================================================================
-bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge,
- list<double> & theParams,
- const bool theReverse) const
+bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
+ double theLength,
+ double theFirstU,
+ double theLastU,
+ list<double> & theParams,
+ const bool theReverse)
{
theParams.clear();
- double f, l;
- Handle(Geom_Curve) Curve = BRep_Tool::Curve(theEdge, f, l);
- GeomAdaptor_Curve C3d (Curve, f, l);
-
- double length = EdgeLength(theEdge);
+ double f = theFirstU, l = theLastU;
switch( _hypType )
{
if ( _hypType == LOCAL_LENGTH )
{
// Local Length hypothesis
- double nbseg = ceil(length / _value[ BEG_LENGTH_IND ]); // integer sup
+ double nbseg = ceil(theLength / _value[ BEG_LENGTH_IND ]); // integer sup
if (nbseg <= 0)
nbseg = 1; // degenerated edge
- eltSize = length / nbseg;
+ eltSize = theLength / nbseg;
}
else
{
case StdMeshers_NumberOfSegments::DT_TabFunc:
{
FunctionTable func(_vvalue[ TAB_FUNC_IND ], _ivalue[ CONV_MODE_IND ]);
- return computeParamByFunc(C3d, f, l, length, theReverse,
+ return computeParamByFunc(theC3d, f, l, theLength, theReverse,
_ivalue[ NB_SEGMENTS_IND ], func,
theParams);
}
case StdMeshers_NumberOfSegments::DT_ExprFunc:
{
FunctionExpr func(_svalue[ EXPR_FUNC_IND ].c_str(), _ivalue[ CONV_MODE_IND ]);
- return computeParamByFunc(C3d, f, l, length, theReverse,
+ return computeParamByFunc(theC3d, f, l, theLength, theReverse,
_ivalue[ NB_SEGMENTS_IND ], func,
theParams);
}
break;
case StdMeshers_NumberOfSegments::DT_Regular:
- eltSize = length / _ivalue[ NB_SEGMENTS_IND ];
+ eltSize = theLength / _ivalue[ NB_SEGMENTS_IND ];
break;
default:
return false;
}
}
- GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l);
+ GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l);
if ( !Discret.IsDone() )
- return false;
+ return error( dfltErr(), "GCPnts_UniformAbscissa failed");
int NbPoints = Discret.NbPoints();
for ( int i = 2; i < NbPoints; i++ )
double param = Discret.Parameter(i);
theParams.push_back( param );
}
- compensateError( eltSize, eltSize, f, l, length, C3d, theParams ); // for PAL9899
+ compensateError( eltSize, eltSize, f, l, theLength, theC3d, theParams ); // for PAL9899
return true;
}
case BEG_END_LENGTH: {
- // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = length
+ // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = theLength
double a1 = _value[ BEG_LENGTH_IND ];
double an = _value[ END_LENGTH_IND ];
- double q = ( length - a1 ) / ( length - an );
+ double q = ( theLength - a1 ) / ( theLength - an );
double U1 = theReverse ? l : f;
double Un = theReverse ? f : l;
double param = U1;
double eltSize = theReverse ? -a1 : a1;
while ( 1 ) {
- // computes a point on a curve <C3d> at the distance <eltSize>
+ // computes a point on a curve <theC3d> at the distance <eltSize>
// from the point of parameter <param>.
- GCPnts_AbscissaPoint Discret( C3d, eltSize, param );
+ GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
if ( !Discret.IsDone() ) break;
param = Discret.Parameter();
if ( param > f && param < l )
break;
eltSize *= q;
}
- compensateError( a1, an, U1, Un, length, C3d, theParams );
+ compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
return true;
}
case ARITHMETIC_1D: {
- // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = length
+ // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = theLength
double a1 = _value[ BEG_LENGTH_IND ];
double an = _value[ END_LENGTH_IND ];
- double q = ( an - a1 ) / ( 2 *length/( a1 + an ) - 1 );
+ double q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
int n = int( 1 + ( an - a1 ) / q );
double U1 = theReverse ? l : f;
q = -q;
}
while ( n-- > 0 && eltSize * ( Un - U1 ) > 0 ) {
- // computes a point on a curve <C3d> at the distance <eltSize>
+ // computes a point on a curve <theC3d> at the distance <eltSize>
// from the point of parameter <param>.
- GCPnts_AbscissaPoint Discret( C3d, eltSize, param );
+ GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
if ( !Discret.IsDone() ) break;
param = Discret.Parameter();
if ( param > f && param < l )
break;
eltSize += q;
}
- compensateError( a1, an, U1, Un, length, C3d, theParams );
+ compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
return true;
}
case DEFLECTION: {
- GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], f, l, true);
+ GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true);
if ( !Discret.IsDone() )
return false;
bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
- MESSAGE("StdMeshers_Regular_1D::Compute");
-
if ( _hypType == NONE )
return false;
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- aMesh.GetSubMesh(aShape);
const TopoDS_Edge & EE = TopoDS::Edge(aShape);
TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
ASSERT(!VFirst.IsNull());
- SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
- if (!lid->more())
- {
- MESSAGE (" NO NODE BUILT ON VERTEX ");
- return false;
- }
- const SMDS_MeshNode * idFirst = lid->next();
-
ASSERT(!VLast.IsNull());
- lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
- if (!lid->more()) {
- MESSAGE (" NO NODE BUILT ON VERTEX ");
- return false;
- }
- const SMDS_MeshNode * idLast = lid->next();
+ const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
+ const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS );
+ if (!idFirst || !idLast)
+ return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
- if (!Curve.IsNull()) {
+ if (!Curve.IsNull())
+ {
list< double > params;
bool reversed = false;
if ( !_mainEdge.IsNull() )
reversed = aMesh.IsReversedInChain( EE, _mainEdge );
- try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
-#endif
- if ( ! computeInternalParameters( E, params, reversed )) {
- //cout << "computeInternalParameters() failed" <<endl;
- return false;
- }
- }
- catch ( Standard_Failure ) {
- //cout << "computeInternalParameters() failed, Standard_Failure" <<endl;
+
+ BRepAdaptor_Curve C3d( E );
+ double length = EdgeLength( E );
+ if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
return false;
}
+ redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
// edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
// only internal nodes receive an edge position with param on curve
const SMDS_MeshNode * idPrev = idFirst;
double parPrev = f;
double parLast = l;
-// if(reversed) {
-// parPrev = l;
-// parLast = f;
-// }
for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
double param = *itU;
else {
// Edge is a degenerated Edge : We put n = 5 points on the edge.
const int NbPoints = 5;
- BRep_Tool::Range(E, f, l);
+ BRep_Tool::Range( E, f, l ); // PAL15185
double du = (l - f) / (NbPoints - 1);
//MESSAGE("************* Degenerated edge! *****************");
- TopoDS_Vertex V1, V2;
- TopExp::Vertices(E, V1, V2);
- gp_Pnt P = BRep_Tool::Pnt(V1);
+ gp_Pnt P = BRep_Tool::Pnt(VFirst);
const SMDS_MeshNode * idPrev = idFirst;
for (int i = 2; i < NbPoints; i++) {
return _usedHypList;
}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & StdMeshers_Regular_1D::SaveTo(ostream & save)
-{
- return save;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & StdMeshers_Regular_1D::LoadFrom(istream & load)
-{
- return load;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp)
-{
- return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_Regular_1D & hyp)
-{
- return hyp.LoadFrom( load );
-}
#include "SMESH_1D_Algo.hxx"
-class TopoDS_Edge;
+class Adaptor3d_Curve;
+class TopoDS_Vertex;
+class StdMeshers_SegmentLengthAroundVertex;
-class STDMESHERS_EXPORT StdMeshers_Regular_1D:
- public SMESH_1D_Algo
+class STDMESHERS_EXPORT StdMeshers_Regular_1D: public SMESH_1D_Algo
{
public:
StdMeshers_Regular_1D(int hypId, int studyId, SMESH_Gen* gen);
virtual const std::list <const SMESHDS_Hypothesis *> &
GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
- ostream & SaveTo(ostream & save);
- istream & LoadFrom(istream & load);
- friend ostream & operator << (ostream & save, StdMeshers_Regular_1D & hyp);
- friend istream & operator >> (istream & load, StdMeshers_Regular_1D & hyp);
+ /*!
+ * \brief Sets event listener to submeshes if necessary
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+ virtual void SetEventListener(SMESH_subMesh* subMesh);
+
+ /*!
+ * \brief Allow algo to do something after persistent restoration
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+ void SubmeshRestored(SMESH_subMesh* subMesh);
protected:
- virtual bool computeInternalParameters (const TopoDS_Edge& theEdge,
+ virtual bool computeInternalParameters (Adaptor3d_Curve & theC3d,
+ double theLength,
+ double theFirstU,
+ double theLastU,
std::list< double > & theParameters,
- const bool theReverse) const;
+ const bool theReverse);
+
+ virtual void redistributeNearVertices (SMESH_Mesh & theMesh,
+ Adaptor3d_Curve & theC3d,
+ double theLength,
+ std::list< double > & theParameters,
+ const TopoDS_Vertex & theVf,
+ const TopoDS_Vertex & theVl);
+
+ /*!
+ * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex
+ */
+ static const
+ StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh & theMesh,
+ const TopoDS_Vertex & theV);
enum HypothesisType { LOCAL_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, NONE };
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentAroundVertex_0D.cxx
+// Module : SMESH
+// Created : Fri Oct 20 11:37:07 2006
+// Author : Edward AGAPOV (eap)
+
+
+#include "StdMeshers_SegmentAroundVertex_0D.hxx"
+
+//=======================================================================
+//function : StdMeshers_SegmentAroundVertex_0D
+//purpose :
+//=======================================================================
+
+StdMeshers_SegmentAroundVertex_0D::StdMeshers_SegmentAroundVertex_0D
+ (int hypId, int studyId, SMESH_Gen* gen)
+ :SMESH_0D_Algo(hypId, studyId, gen)
+{
+ _name = "SegmentAroundVertex_0D";
+ // it is assigned to vertices but influence a state of EDGE submeshes
+ _shapeType = (1 << TopAbs_VERTEX); // 1 bit per shape type
+
+ _compatibleHypothesis.push_back("SegmentLengthAroundVertex");
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_SegmentAroundVertex_0D::~StdMeshers_SegmentAroundVertex_0D()
+{}
+
+//=======================================================================
+//function : CheckHypothesis
+//purpose :
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ list <const SMESHDS_Hypothesis * >::const_iterator itl;
+
+ const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+ if ( hyps.size() == 0 )
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
+
+ if ( hyps.size() > 1 )
+ {
+ aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+ }
+ else
+ {
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+ return ( aStatus == HYP_OK );
+}
+
+//=======================================================================
+//function : Compute
+//purpose :
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
+{
+ // This algorithm exists in order just to enable assignation of
+ // StdMeshers_SegmentLengthAroundVertex hypothesis
+ return true;
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentAroundVertex_0D.hxx
+// Module : SMESH
+
+#ifndef _SMESH_SegmentAroundVertex_0D_HXX_
+#define _SMESH_SegmentAroundVertex_0D_HXX_
+
+#include "SMESH_0D_Algo.hxx"
+
+/*!
+ * \brief Algorithm existing in order just to enable assignation of
+ * StdMeshers_SegmentLengthAroundVertex hypothesis
+ */
+class StdMeshers_SegmentAroundVertex_0D: public SMESH_0D_Algo
+{
+public:
+ StdMeshers_SegmentAroundVertex_0D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_SegmentAroundVertex_0D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentLengthAroundVertex.cxx
+// Module : SMESH
+// $Header$
+
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
+
+#include "SMESH_Mesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex::StdMeshers_SegmentLengthAroundVertex
+ (int hypId, int studyId, SMESH_Gen * gen)
+ :SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _length = 1.;
+ _name = "SegmentLengthAroundVertex";
+ _param_algo_dim = 0; // is used by StdMeshers_SegmentAroundVertex_0D
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex::~StdMeshers_SegmentLengthAroundVertex()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_SegmentLengthAroundVertex::SetLength(double length) throw(SALOME_Exception)
+{
+ if (length <= 0)
+ throw SALOME_Exception(LOCALIZED("length must be positive"));
+ if (_length != length) {
+ _length = length;
+ NotifySubMeshesHypothesisModification();
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_SegmentLengthAroundVertex::GetLength() const
+{
+ return _length;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_SegmentLengthAroundVertex::SaveTo(ostream & save)
+{
+ save << this->_length;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_SegmentLengthAroundVertex::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ double a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_length = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_SegmentLengthAroundVertex & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_SegmentLengthAroundVertex & hyp)
+{
+ return hyp.LoadFrom( load );
+}
+
+//================================================================================
+/*!
+ * \brief Initialize segment length by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_SegmentLengthAroundVertex::SetParametersByMesh(const SMESH_Mesh* theMesh,
+ const TopoDS_Shape& theShape)
+{
+ if ( !theMesh || theShape.IsNull() || theShape.ShapeType() != TopAbs_VERTEX )
+ return false;
+
+ SMESH_MeshEditor editor( const_cast<SMESH_Mesh*>( theMesh ) );
+ SMESH_MesherHelper helper( *editor.GetMesh() );
+
+ // get node built on theShape vertex
+ SMESHDS_Mesh* meshDS = editor.GetMeshDS();
+ SMESHDS_SubMesh* smV = meshDS->MeshElements( theShape );
+ if ( !smV || smV->NbNodes() == 0 )
+ return false;
+ const SMDS_MeshNode* vNode = smV->GetNodes()->next();
+
+ // calculate average length of segments sharing vNode
+
+ _length = 0.;
+ int nbSegs = 0;
+
+ SMDS_ElemIteratorPtr segIt = vNode->GetInverseElementIterator(SMDSAbs_Edge);
+ while ( segIt->more() ) {
+ const SMDS_MeshElement* seg = segIt->next();
+ // get geom edge
+ int shapeID = editor.FindShape( seg );
+ if (!shapeID) continue;
+ const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
+ if ( s.IsNull() || s.ShapeType() != TopAbs_EDGE ) continue;
+ const TopoDS_Edge& edge = TopoDS::Edge( s );
+ // params of edge ends
+ double u0 = helper.GetNodeU( edge, seg->GetNode(0) );
+ double u1 = helper.GetNodeU( edge, seg->GetNode(1) );
+ // length
+ BRepAdaptor_Curve AdaptCurve( edge );
+ _length += GCPnts_AbscissaPoint::Length( AdaptCurve, u0, u1);
+ nbSegs++;
+ }
+
+ if ( nbSegs > 1 )
+ _length /= nbSegs;
+
+ return nbSegs;
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentLengthAroundVertex.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_SegmentLengthAroundVertex_HXX_
+#define _SMESH_SegmentLengthAroundVertex_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+/*!
+ * \brief This hypothesis specifies length of segments adjacent to the vertex the
+ * hypothesis is assigned to
+ */
+class StdMeshers_SegmentLengthAroundVertex:public SMESH_Hypothesis
+{
+ public:
+ StdMeshers_SegmentLengthAroundVertex(int hypId, int studyId, SMESH_Gen * gen);
+ virtual ~ StdMeshers_SegmentLengthAroundVertex();
+
+ void SetLength(double length) throw(SALOME_Exception);
+
+ double GetLength() const;
+
+ virtual std::ostream & SaveTo(std::ostream & save);
+ virtual std::istream & LoadFrom(std::istream & load);
+ friend std::ostream & operator <<(std::ostream & save, StdMeshers_SegmentLengthAroundVertex & hyp);
+ friend std::istream & operator >>(std::istream & load, StdMeshers_SegmentLengthAroundVertex & hyp);
+
+ /*!
+ * \brief Initialize segment length by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+ protected:
+ double _length;
+};
+
+#endif
}
}
-//================================================================================
-/*!
- * \brief Widget: slider with left and right labels
- */
-//================================================================================
+namespace {
-class TDoubleSliderWith2Lables: public QHBox
-{
-public:
- TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel,
- const double initValue, const double bottom,
- const double top , const double precision,
- QWidget * parent=0 , const char * name=0 )
- :QHBox(parent,name), _bottom(bottom), _precision(precision)
- {
- if ( !leftLabel.isEmpty() ) (new QLabel( this ))->setText( leftLabel );
- _slider = new QSlider( Horizontal, this );
- _slider->setRange( 0, toInt( top ));
- _slider->setValue( toInt( initValue ));
- if ( !rightLabel.isEmpty() ) (new QLabel( this ))->setText( rightLabel );
- }
- double value() const { return _bottom + _slider->value() * _precision; }
- QSlider * getSlider() const { return _slider; }
- int toInt( double val ) const { return (int) ceil(( val - _bottom ) / _precision ); }
-private:
- double _bottom, _precision;
- QSlider * _slider;
-};
+ //================================================================================
+ /*!
+ * \brief Widget: slider with left and right labels
+ */
+ //================================================================================
-namespace {
+ class TDoubleSliderWith2Lables: public QHBox
+ {
+ public:
+ TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel,
+ const double initValue, const double bottom,
+ const double top , const double precision,
+ QWidget * parent=0 , const char * name=0 )
+ :QHBox(parent,name), _bottom(bottom), _precision(precision)
+ {
+ if ( !leftLabel.isEmpty() ) (new QLabel( this ))->setText( leftLabel );
+ _slider = new QSlider( Horizontal, this );
+ _slider->setRange( 0, toInt( top ));
+ _slider->setValue( toInt( initValue ));
+ if ( !rightLabel.isEmpty() ) (new QLabel( this ))->setText( rightLabel );
+ }
+ double value() const { return _bottom + _slider->value() * _precision; }
+ QSlider * getSlider() const { return _slider; }
+ int toInt( double val ) const { return (int) ceil(( val - _bottom ) / _precision ); }
+ private:
+ double _bottom, _precision;
+ QSlider * _slider;
+ };
//================================================================================
/*!
h->SetLength( params[0].myValue.toDouble() );
}
+ else if( hypType()=="SegmentLengthAroundVertex" )
+ {
+ StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h =
+ StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() );
+
+ h->SetLength( params[0].myValue.toDouble() );
+ }
else if( hypType()=="Arithmetic1D" )
{
StdMeshers::StdMeshers_Arithmetic1D_var h =
item.myValue = h->GetLength();
p.append( item );
}
+ else if( hypType()=="SegmentLengthAroundVertex" )
+ {
+ StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h =
+ StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hyp );
+
+ item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
+ item.myValue = h->GetLength();
+ p.append( item );
+ }
else if( hypType()=="Arithmetic1D" )
{
StdMeshers::StdMeshers_Arithmetic1D_var h =
types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" );
types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" );
types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" );
+ types.insert( "SegmentLengthAroundVertex", "SEGMENT_LENGTH_AROUND_VERTEX" );
}
QString res;
msgid "ICON_DLG_LOCAL_LENGTH"
msgstr "mesh_hypo_length.png"
+msgid "ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX"
+msgstr "mesh_hypo_length.png"
+
msgid "ICON_DLG_NB_SEGMENTS"
msgstr "mesh_hypo_segment.png"
msgid "ICON_SMESH_TREE_ALGO_Regular_1D"
msgstr "mesh_tree_algo_regular.png"
+msgid "ICON_SMESH_TREE_ALGO_CompositeSegment_1D"
+msgstr "mesh_tree_algo_regular.png"
+
msgid "ICON_SMESH_TREE_ALGO_Hexa_3D"
msgstr "mesh_tree_algo_hexa.png"
msgid "ICON_SMESH_TREE_HYPO_ProjectionSource3D"
msgstr "mesh_tree_hypo_source_3d_shape.png"
+
+msgid "ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D"
+msgstr "mesh_tree_algo_regular.png"
+
+msgid "ICON_SMESH_TREE_HYPO_SegmentLengthAroundVertex"
+msgstr "mesh_tree_hypo_length.png"
msgid "StdMeshersGUI_LayerDistributionParamWdg::EDIT"
msgstr "Edit"
+
+# -------------- Segment Length Around Vertex --------------
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS"
+msgstr "Segment Length Around Vertex"
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM"
+msgstr "Length"
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE"
+msgstr "Hypothesis Construction"
+
StdMeshers_Projection_1D_2D_3D_i.hxx \
StdMeshers_ObjRefUlils.hxx \
StdMeshers_LayerDistribution_i.hxx \
+ StdMeshers_CompositeSegment_1D_i.hxx \
+ StdMeshers_SegmentAroundVertex_0D_i.hxx \
+ StdMeshers_SegmentLengthAroundVertex_i.hxx \
SMESH_StdMeshers_I.hxx
# Libraries targets
StdMeshers_ProjectionSource3D_i.cxx \
StdMeshers_Projection_1D_2D_3D_i.cxx \
StdMeshers_ObjRefUlils.cxx \
- StdMeshers_LayerDistribution_i.cxx
+ StdMeshers_LayerDistribution_i.cxx \
+ StdMeshers_CompositeSegment_1D_i.hxx \
+ StdMeshers_SegmentAroundVertex_0D_i.hxx \
+ StdMeshers_SegmentLengthAroundVertex_i.hxx
# additionnal information to compil and link file
libStdMeshersEngine_la_CPPFLAGS = \
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_CompositeSegment_1D_i.cxx
+// Module : SMESH
+// $Header$
+
+#include "StdMeshers_CompositeSegment_1D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i
+ ( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_1D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i" );
+ myBaseImpl = new ::StdMeshers_CompositeSegment_1D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i()
+{
+ MESSAGE( "StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_CompositeSegment_1D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_CompositeSegment_1D* StdMeshers_CompositeSegment_1D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_CompositeSegment_1D_i::GetImpl" );
+ return ( ::StdMeshers_CompositeSegment_1D* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_CompositeSegment_1D_i.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_CompositeSegment_1D_I_HXX_
+#define _SMESH_CompositeSegment_1D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_1D_Algo_i.hxx"
+#include "StdMeshers_CompositeSegment_1D.hxx"
+
+// ======================================================
+// Wire Discretization 1d algorithm
+// ======================================================
+class StdMeshers_CompositeSegment_1D_i:
+ public virtual POA_StdMeshers::StdMeshers_CompositeSegment_1D,
+ public virtual SMESH_1D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_CompositeSegment_1D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_CompositeSegment_1D_i();
+
+ // Get implementation
+ ::StdMeshers_CompositeSegment_1D* GetImpl();
+};
+
+#endif
//=============================================================================
StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA,
- int theStudyId,
- ::SMESH_Gen* theGenImpl )
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
: SALOME::GenericObj_i( thePOA ),
SMESH_Hypothesis_i( thePOA ),
SMESH_Algo_i( thePOA ),
{
MESSAGE( "StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i" );
myBaseImpl = new ::StdMeshers_Regular_1D( theGenImpl->GetANewId(),
- theStudyId,
- theGenImpl );
+ theStudyId,
+ theGenImpl );
}
//=============================================================================
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_Projection_3D_i.cxx
+// Moved here from SMESH_Projection_3D_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i
+ */
+//=============================================================================
+
+StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i
+ ( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_0D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i" );
+ myBaseImpl = new ::StdMeshers_SegmentAroundVertex_0D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+//-----------------------------------------------------------------------------
+
+StdMeshers_SegmentAroundVertex_0D_i::~StdMeshers_SegmentAroundVertex_0D_i()
+{
+ MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::~StdMeshers_SegmentAroundVertex_0D_i" );
+}
+//-----------------------------------------------------------------------------
+
+::StdMeshers_SegmentAroundVertex_0D* StdMeshers_SegmentAroundVertex_0D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::GetImpl" );
+ return ( ::StdMeshers_SegmentAroundVertex_0D* )myBaseImpl;
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentAroundVertex_0D.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_SegmentAroundVertex_0D_I_HXX_
+#define _SMESH_SegmentAroundVertex_0D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_0D_Algo_i.hxx"
+#include "StdMeshers_SegmentAroundVertex_0D.hxx"
+
+class SMESH_Gen;
+
+class StdMeshers_SegmentAroundVertex_0D_i:
+ public virtual POA_StdMeshers::StdMeshers_SegmentAroundVertex_0D,
+ public virtual SMESH_0D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_SegmentAroundVertex_0D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+
+ // Destructor
+ virtual ~StdMeshers_SegmentAroundVertex_0D_i();
+
+ // Get implementation
+ ::StdMeshers_SegmentAroundVertex_0D* GetImpl();
+};
+
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentLengthAroundVertex_i.cxx
+// Module : SMESH
+// $Header$
+
+#include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i
+ ( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i" );
+ myBaseImpl = new ::StdMeshers_SegmentLengthAroundVertex( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i()
+{
+ MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentLengthAroundVertex_i::SetLength
+ *
+ * Set length
+ */
+//=============================================================================
+
+void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::SetLength" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetLength( theLength );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM );
+ }
+
+ // Update Python script
+ SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentLengthAroundVertex_i::GetLength
+ *
+ * Get length
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_SegmentLengthAroundVertex_i::GetLength()
+{
+ MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetLength" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetLength();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_SegmentLengthAroundVertex_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_SegmentLengthAroundVertex* StdMeshers_SegmentLengthAroundVertex_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetImpl" );
+ return ( ::StdMeshers_SegmentLengthAroundVertex* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type
+ * \param type - dimension (see SMESH::Dimension enumeration)
+ * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ *
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================
+
+CORBA::Boolean StdMeshers_SegmentLengthAroundVertex_i::IsDimSupported( SMESH::Dimension type )
+{
+ return type == SMESH::DIM_1D;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : StdMeshers_SegmentLengthAroundVertex_i.hxx
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_SegmentLengthAroundVertex_I_HXX_
+#define _SMESH_SegmentLengthAroundVertex_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
+
+class SMESH_Gen;
+
+/*!
+ * \brief This hypothesis specifies length of segments adjacent to the vertex the
+ * hypothesis is assigned to
+ */
+class StdMeshers_SegmentLengthAroundVertex_i:
+ public virtual POA_StdMeshers::StdMeshers_SegmentLengthAroundVertex,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_SegmentLengthAroundVertex_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_SegmentLengthAroundVertex_i();
+
+ // Set length
+ void SetLength( CORBA::Double theLength )
+ throw ( SALOME::SALOME_Exception );
+
+ // Get length
+ CORBA::Double GetLength();
+
+ // Get implementation
+ ::StdMeshers_SegmentLengthAroundVertex* GetImpl();
+
+ // Verify whether hypothesis supports given entity type
+ CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
#include "StdMeshers_MaxElementArea_i.hxx"
#include "StdMeshers_MaxElementVolume_i.hxx"
#include "StdMeshers_NotConformAllowed_i.hxx"
-
#include "StdMeshers_ProjectionSource3D_i.hxx"
#include "StdMeshers_ProjectionSource2D_i.hxx"
#include "StdMeshers_ProjectionSource1D_i.hxx"
#include "StdMeshers_NumberOfLayers_i.hxx"
#include "StdMeshers_LayerDistribution_i.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
#include "StdMeshers_Regular_1D_i.hxx"
#include "StdMeshers_MEFISTO_2D_i.hxx"
#include "StdMeshers_Quadrangle_2D_i.hxx"
#include "StdMeshers_Hexa_3D_i.hxx"
-
#include "StdMeshers_Projection_1D_2D_3D_i.hxx"
#include "StdMeshers_Prism_3D_i.hxx"
+#include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
+#include "StdMeshers_CompositeSegment_1D_i.hxx"
template <class T> class StdHypothesisCreator_i:public HypothesisCreator_i<T>
aCreator = new StdHypothesisCreator_i<StdMeshers_NumberOfLayers_i>;
else if (strcmp(aHypName, "LayerDistribution") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_LayerDistribution_i>;
+ else if (strcmp(aHypName, "SegmentLengthAroundVertex") == 0)
+ aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentLengthAroundVertex_i>;
// Algorithms
else if (strcmp(aHypName, "Regular_1D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i>;
else if (strcmp(aHypName, "RadialPrism_3D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_RadialPrism_3D_i>;
+ else if (strcmp(aHypName, "SegmentAroundVertex_0D") == 0)
+ aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentAroundVertex_0D_i>;
+ else if (strcmp(aHypName, "CompositeSegment_1D") == 0)
+ aCreator = new StdHypothesisCreator_i<StdMeshers_CompositeSegment_1D_i>;
else ;
return aCreator;